> ability to hide a lot of things, including control flow, and often do
They're still local transformations though, so I would think they're either:
- Choosing between their arguments somehow e.g. like `(unless condition body)` expanding to `(if (not condition) body)`, or `(with-foo body)` running `body` inside some setup/teardown boilerplate. In such cases we just need local reasoning (possibly after expanding the macros; but like functions, if you have to keep reading the definition to see what it's for, the abstraction it provides has been lost)
- Invoking other code (macros and functions); but functions can do this too, so such non-local reasoning is essentially the same.
A phrase like "hiding control flow" sounds scary, like we're implementing "GOTO" all over the place (or `call/cc` or something). Yet macros themselves can't do that; they could only do GOTO-like-stuff if there are GOTO-like constructs in the language, in which case (a) that's what's causing the underlying difficulty and (b) functions can presumably do similar shenanigans.
I must admit that I do most programming in Haskell these days, so I take it for granted that I can implement my own control flow using ordinary functions (thanks to laziness). That's just as well, since Haskell's macros (Template Haskell) are pretty gnarly; they're very useful on occasion though (e.g. I'm currently working on a script which reads in and parses a bunch of JSON from a filename (taken from an environment variable) at compile time, building a datastructure that I can query at runtime).
> which often makes them unable to be composed
Composed in what sense? I get that we can't e.g. pass macros to higher-order functions, and things like that; but I wouldn't say that's especially due to their use for control flow. I'm more frustrated by the general asymmetry between functions and macros, which can cause us to write the same functionality multiple times (I have the same frustration in languages which distinguish between functions and operators, functions and methods, statements and expressions, objects and "primitives", etc.).