4 ms·
Macros are a kind of function that have the ability to hide a lot of things, including control flow, and often do, which often makes them unable to be composed.
by sdegutis 8y ago
Macros are a kind of function that have the ability to hide a lot of things, including control flow, and often do, which often makes them unable to be composed. That's why I put them between languages and libs. They're a little less flexible than regular functions/methods/classes and they usually have tighter lock-in.
- chriswarbo 8y ago> 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.).