16 ms·
The end result with macros is far more seamless than with codegen, the point being that a consumer of the library doesn't even need to know about the macros. Th
by phamilton 8y ago
The end result with macros is far more seamless than with codegen, the point being that a consumer of the library doesn't even need to know about the macros. The code just works like the reflection approach, but without the runtime penalty. Codegen on the other hand makes an implementation detail a maintenance cost for the user of the library.
- stcredzero 8y agoThe end result with macros is far more seamless than with codegen, the point being that a consumer of the library doesn't even need to know about the macros. A double edged sword, that! Sometimes the end result with things like macros, is that it so seamless, that there is precious little to figure out what went wrong. Often, if your nifty new facility seems magic, its bugs are going to seem doubly magic. Not too long ago, I had to debug an exception for which no source code existed. It only existed as the confluence of 3 C++ templates. Codegen on the other hand makes an implementation detail a maintenance cost for the user of the library. I've heard veteran programmers say that there should be a separation of labor when it comes to libraries. Only certain people make good library writers, in the same way that only certain people make excellent musical accompanists. To be an excellent accompanist, the accompanist should have some sense of what it's like to be the lead. (So should themselves be able to take the lead.) The accompanist should have the perspective to not let his ego get in the way. The accompanist should be giving the lead what she wants, but modulated through their own expertise and sense of taste. (As opposed to mindlessly always giving everything asked for.) If there is a separation of responsibility, why would codegen be such a burden? If the library has to change so often, perhaps the responsibilities aren't distributed optimally?
- pcwalton 8y agoMacros usually make debugging easier than code generators do. That's because quasiquote and similar operators let you debug code, not code that generates code. I'm the first to admit that macros have downsides compared to not having them in the language, but ease of debugging generated code isn't one of those downsides.
- stcredzero 8y agoI've generally found that C/C++ macros make debugging harder. Debuggers don't always deal with debugging them the most straightforward thing. That's because quasiquote and similar operators let you debug code, not code that generates code. What I've found is that you can debug the generated code to debug the code generator. Code generators shouldn't be used to do something terribly complicated. I'd agree with you that code generators doing complicated things is a code smell. Leave those to native syntax, provided it's not as badly thought out as templates.
- phamilton 8y ago> C/C++ macros I'd argue that those aren't first class macros. C macros are just source manipulators, and C++ templates (I'm not super experienced with them so forgive come if I'm way off) don't really manipulate the AST, it's more a type system with compile time resolution.
- phamilton 8y ago> A double edged sword, that! Sometimes the end result with things like macros, is that it so seamless, that there is precious little to figure out what went wrong. First class macros generally contain the same logic as a reflection based approach, but they execute at compile-time and memoize the result. If you can debug compilation (which languages with first class macros generally support), then debugging is roughly the same. There are definitely cases where that's not true, but in this domain (serialization) a macro based solution is well understood. See https://github.com/devinus/poison/blob/62e98f19552289f3f7139aca438ce2b169c54796/lib/poison/encoder.ex#L344 https://github.com/devinus/poison/blob/62e98f19552289f3f7139... for a macro based example in Elixir.