As always, I'm very glad to see that structural, Common Lisp-style macro systems with the whole language available for macro construction, have been successfully adopted in other languages to the point where it's possible to explain them without a single mention of Lisp in the article, or even better - where a mention of Lisp anywhere else except for the very beginning would make the article <i>worse</i> by making a unnecessary detour.<p>pg's article on the topic, "What Made Lisp Different", [0] has aged poorly, and points 8 and 9 it makes (a notation for code using trees of symbols and the whole language always available) are no longer Lisp-specific. The final point, about "inventing a new dialect of Lisp", doesn't hold true either - as seen here, Julia is doing just fine not claiming to be another dialect of Lisp, even though many sources mention directly that it's Lisp-inspired.<p>Congrats to Julia people for the macro system and to the author for the article!<p>[0] <a href="http://www.paulgraham.com/diff.html" rel="nofollow">http://www.paulgraham.com/diff.html</a>
Macros were part of the "holy shit" moment for me for Lisp, in particular the Common Lisp Object System. I hadn't fully realized that it was possible to add a whole new <i>paradigm</i> to a language as a <i>library</i> [1], and moreover a particularly nice implementation of that paradigm.<p>After that, I realized that macros aren't <i>always</i> something that needs to be avoided; in the right hands they're immensely powerful.<p>I've only played a little with Julia macros, but it seems like they learned a lot of Lisps lessons, so I support it wholly.<p>[1] I wasn't aware of how Objective C was built at the time.
The frustration of Julia macros for me was never knowing what AST would be produced for a given expression. This is a bit more manageable if you have a typed AST (e.g. OCaml but ppxes have other issues) or an obvious one (e.g. lisp). I like the way rust handles it where the macros operate on a tree of non-delimiter leaves and [delimiter, subtree list, delimiter] nodes which can allow for figuring out what the input to a macro will be more easily and for more varied macro syntax. Other languages that want a full AST before macros force the macro input to be a bit more AST-like, e.g. the Julia parser picks operator precedence and OCaml won’t let you use _ as an identifier.<p>Maybe it is better now but when I looked at macros ~5 years ago some language update changed the ast produced by the parser and I basically gave up.<p>I like that Julia offers some macro-like techniques that replace a lot of the cases where one might use a macro for performance reasons.