There is much that can be done with regular, bog-standard functions. Yes, macros can be useful in certain cases, but it's often more straightforward to use the Lisp language as it comes. As always, it's important to use the right tool for the job.
> You cannot implement simple, modular, debuggable, composable DSLs with functions alone.
We've been doing this for at least ten years. Example: [1]
For someone who's convinced that DSL's are the silver bullet that everybody should be using, you don't seem to have kept up with the state of the art of the field much.
These are functions, it doesn't get any simpler than that and it doesn't require learning anything new once you know the language.
Macros are over engineered in comparison since they force the developer to learn a whole new section of the language with its own rules and own compilation lifecycle.
This is why hardly anyone uses macros these days and why most language are embracing the Groovy/Kotlin approach to writing DSL's.
Free monads would like to have a word with you about simple, modular, debuggable, composable DSLs. On the other hand macros are anything but composable or modular. Debuggable for some far off definition of debuggable, maybe.
Monadic interpreters? Composable? Are you kidding? It is a joke, not a composability. You cannot take a type system of one DSL, modules from another and only the expressions syntax from a third one and then mix them all together into a new DSL.
And, anyway, interpreters. Who in a sane mind can ever consider an interpreter?
Also, you obviously do not realise that macro-based DSLs are by far more debuggable than any monadic interpreter would ever be.
I do not believe such a thing exist. Macros are the ultimate solution.