4 ms·
Clojure had this same property, and it seems like a benefit at first: because new "language features" aren't tied to releases of the language, anyone can create
by sdegutis 8y ago
Clojure had this same property, and it seems like a benefit at first: because new "language features" aren't tied to releases of the language, anyone can create them and instantly share them with the community for everyone to immediately start using.
A great example is destructuring, which someone wrote a macro for, around version 1.2 or so, that got bundled with the language shortly after. You can't do that without changing the language, or being able to extend it with macros.
But in practice, having community-written macros means you'll get several versions of the same one, and there often won't be any clear winner since each will have strengths and weaknesses, and at least some authors will be unwilling to merge or add features or change their version, so that you end up with a bunch of almost-perfect macros and have to settle for their annoying bugs that you know you could fix in 5 minutes if you just made a private fork, but then you end up in the xkcd-standards paradox.
Babel showed that you can successfully achieve the same thing macros do, but outside of the language, by writing a compiler and just targets the language you want to execute. No need for macros to get destructuring, just enable the "destructuring" plugin.
Unfortunately, Babel misses the mark on this dream, because literally every Babel "plugin" is actually implemented in Babel's core library and all the plugins do is just enable a flag or two in the core parser/compiler. It doesn't expose any parser or compiler for you, and you can't actually add new tokens without forking Babel.
- wrs 8y agoI don’t see how this means Babel is better than macros, except that it’s harder to write syntax transformations if you have to “write a compiler”, so fewer people do it. Is your point that you shouldn’t use new syntax until it gets into the ES standard?
- TeMPOraL 8y agoChanging a macro you own > forking a macro library > forking a transpiler > forking the language. I admit I never worked with Babel on the plugin-writing side, but that sounds much more complex than writing macros. With Clojure macros, and Lisp macros in general, one of the important part is that they run within the same system as the rest of your code. That is, macro logic can be split out to regular functions, that will be executed at compile-time. Macros can reuse functions you wrote to be used at runtime. This property makes a language and your codebase much more coherent wrt. macro use.
- taeric 8y agoHow is this any different than any other library? Basically, you shouldn't pull in a dependency that permeates your entire codebase. That it is a macro based library shouldn't change this. Right? Language features often blur this, because people attach an unreasonably high level of trust on them not changing. Used to be, this was completely warranted. Truth to tell, probably mostly warranted even today. However, this does mean you go at a much slower pace pulling in those features. And, the more any of these permeate what you are doing, the less you are in control of what it is you are doing. Probably fine for many cases, but this is the definition of technical debt. You are taking out a loan on someone else's technical asset (code) to accomplish your goal. I liken this to being a kitchen builder. If you are just trying to build a few quick kitchen's in standard layouts, Ikea/HomeDepot/Lowes all have fabricated cabinets that are actually quite serviceable and likely build what you want. As soon as you are getting non-standard, those will start to cause some grief, and having not built up experience with custom cabinets is likely to be a source of trouble.
- fouric 8y agoWould you be willing to provide an example of the "multiple incompatible implementations of the same macro" situation happening in the real world? I've been writing (modest) macros in CL for several years now, and never seen this occur - I've only seen "upgrading" where macro authors layer functionality onto existing macros in such a way that is mostly compatible with the original (such as sjl's extension of WHEN-LET/IF-LET to WHEN-LET* / IF-LET* [1], which I believe are compatible with the Alexandria implementations of the former), although it's quite likely that I simply don't have the experience to have encountered this situation. [1] http://stevelosh.com/blog/2018/07/fun-with-macros-if-let/ http://stevelosh.com/blog/2018/07/fun-with-macros-if-let/