4 ms·
> In general, I'd advise against them Why? Macros are the single most important productivity feature in Lisps. Macros allow to implement eDSLs trivially, in
by sklogic 11y ago
> In general, I'd advise against them
Why? Macros are the single most important productivity feature in Lisps.
Macros allow to implement eDSLs trivially, in the most robust way possible. Yes, you need to follow a certain discipline, but once you get it, you won't ever want to touch a language without macros.
- dmichulke 11y agoMost of the macros in libraries were saving a pair of parentheses at the cost of making code more obscure and, well, less explicit. A few co-workers also liked macros alot so they did stuff that could have been done in functions. I suppose my experience is that clojure's core macros are sufficient and/or I never saw a good eDSL that would have been worse without macros. (Input is welcome) Also, I don't feel I missed out on something because the biggest productivity features for me are being functional, maps-as-objects + dynamic typing, destructuring, emacs (yeah I know), immutability, threaded execution via pmap, Java libs. However, I suppose these productivity features depend strongly on where you come from (for me: Java)
- sklogic 11y ago> Most of the macros in libraries were saving a pair of parentheses This is an epic misuse of macros. > and/or I never saw a good eDSL that would have been worse without macros eDSLs should almost never be implemented without macros (unless they're message DSLs). Macro, essentially, is a compiler. The only alternative is to implement an ad hoc interpreter. And compilers are much, much easier to write, debug and maintain than interpreters - for some very trivial reasons. Compilers can be split into sequences of very simple stages, each doing something simple and comprehensible. It's easy to debug, easy to insert additional steps in between, easy to cut off at any point and replace the backend with something totally different. Interpreters are deeply tangled, naturally, there is no way to modularise them. > the biggest productivity features for me are being functional Using macros and eDSLs is another huge step forward in productivity that will dwarf everything you liked so far in FP.
- eutectic 11y ago> The only alternative is to implement an ad hoc interpreter. You could also have your eDSL calls act as data constructors for an AST and then implement an `eval` function which invokes a run-time compiler.
- sklogic 11y agoThis is not any different from a macro. You still translate your DSL into your host language AST, with the only final step different - runtime eval instead of a compile-time macro. All my macros look like (defmacro something (dsl) (compile-dsl-whatever dsl)). You can always pass the same (compile-dsl-whatever dsl) to (eval ...).
- dkersten 11y agoI've been very successfully applying the data > functions > macros guideline. Yes, this makes eDSL's look very clojurey, but in practice I've not seen this to be a problem. That is: prefer a data-structure based DSL (eg Datomic queries) if possible. If not, prefer function composition. Failing that, macros to the rescue.
- huahaiy 11y agoMy understanding is that the Clojure community discourages the use of macro. The preference is to use data over functions, and functions over macro. The reason is that macros do not compose well. Yes, macros are good for developing DSLs, so they are mostly used in developing libraries, but most application developers do not need to use macro. The wide spread macro usage probably contributed to the fragmentation of CL community. Taking such lessons to heart, Clojure library authors tend to reuse commonly accepted DSL forms, e.g. hiccup is the DSL for writing HTML, and most authors have adopted it when developing their own libraries. I think this is a good thing.
- sklogic 11y agoThen the entire community got it all wrong. DSLs are much, much more composable than functions. You can easily compose just parts of DSLs, building new DSLs on top by combining semantic properties from the existing DSLs. It's just a very different way of thinking about programming in general, and many people just don't get it.
- kazinator 11y agoMacros look like the single most important productivity feature in Lisps only when we are comparing to languages that have borrowed almost everything else, so that we are discounting those other things, consciously or not.
- sklogic 11y agoI'd trade any language without macros to the same language, but with the proper macros added. And then I'll get all the features I want - lambdas, garbage collection, numeric tower, lazy evaluation, any imaginable type system, whatever else (of course, there are some limits, I would not be able to get an image-based system and a REPL if the host language runtime does not allow it). It's a nearly infinite flexibility, no other single feature or a combination of language features can do this.