One thing monad/bind can do that macros cannot is make arbitrary runtime decisions about what to do next, with runtime information. A macro is constrained by what is known statically in the AST. This is why compiled languages are far easier to optimize (it is merely algebraic rewrites of the AST) whereas dynamic languages have runtime eval.
One thing monad/bind can do that macros cannot is make arbitrary runtime decisions about what to do next, with runtime information. A macro is constrained by what is known statically in the AST. This is why compiled languages are far easier to optimize (it is merely algebraic rewrites of the AST) whereas dynamic languages have runtime eval.