5 ms·
You make some good points but I disagree with: 4. Macros: Many other languages have good macros now (Elixir, Rust, etc). It can be useful in certain situations
by papaf 6y ago
You make some good points but I disagree with:
4. Macros: Many other languages have good macros now (Elixir, Rust, etc). It can be useful in certain situations, especially how it's used in Rust's stdlib and third party libs, but it's not a panacea as commonly thought.
For me, the big deal with lisp macros, is that you write the macros in lisp itself and can call lisp functions at compile time.
The last time I wrote a Rust Macro they only supported pattern matching and templating -- any rust code was only run by the final compiled program. Have Rust macros got that much more powerful now?
- geofft 6y agoThe built-in macros haven't but there's good support for procedural macros ("proc macros"), which are Rust code run at compile time that transform AST to AST. However, this is "just" a particularly well-polished form of compiler plugins - technically you can run C code at compile time with a GCC plugin, do cool things with libclang, etc. Writing project-specific compiler plugins is unusual but not totally unheard of: Linux has a couple, for instance.
- didibus 6y agoYa, OP is underestimating Lisp macros, the biggest of which is that Lisps tend to bundle their compilers within their runtime, so macros can actually expand at runtime, since compilation happens at runtime. The other of which is that they are so easy to write, that they just become another tool you use on a constant basis, just like you'd write a function, you write a macro, no big deal. I don't know that most Rust users have busted out a Rust macro or ever will. And one more of which is that macros are so well integrated, the languages themselves are implemented almost entirely with them. The number of compiler forms you need is very small. I think Common Lisp has like 30 compiler forms, and Clojure like 20, Scheme must be even less. That's all you need. This is why Clojure has a JavaScript, C#, Erlang, C++ and Go dialect as well as the default Java one, because you don't have that much work to do in the compiler, everything else just re-use the macros. I'll give in to Elixir, whose macros are pretty good, and for which I like the language, obviously, since it's like a Clojure with a different syntax and Beam instead of Java :p. Still would have preferred they'd just go with a full Lisp syntax and macro system, but oh well, a Lispyfied Ruby shall do. But ya, most other languages, even those trying to have more macro support like Nim, Rust, Julia, don't fully approach Lisp macros, even if some gets pretty close, like Elixir. Also, I don't know if comparing other niche languages with a niche language is a very good overall comparison.
- eigenspace 6y agoI'd say Julia's macros are basically at a lisp level. The main difference between Julia and lisp macros is that julia has more syntactic forms so macro writing has some extra cognitive overhead.
- didibus 6y agoHaven't looked at them in a while, but already that difference there is my second listed point above. So it's no small difference. I'd also like to flip the question around: Why do these other languages bother with complicated syntaxes and then try and spend so much energy in trying to close the gap with Lisp Macros? Why don't they just go with a Lisp syntax from the get go? I know the answer is they want non Lispers to use their language :p But seriously that's frustrating to a Lisper like me. Julia would be beautiful if it had a Lisp syntax.
- snicker7 6y ago> Julia would be beautiful if it had a Lisp syntax. It don't think it would. Lisp achieves its homoiconicity by using the same structure for data and code: the (possibly nested) list. This allows data and code to be manipulated in similar ways. Julia, unlike Lisp or APL, doesn't prescribe a preferred data structure (and shouldn't, considering its emphasis on performance).
- didibus 6y agoI'm not sure I understand the issue your are pointing out? Julia calls itself homoiconic, it uses Expr to model its AST and the parser returns it. There's even a show_expr method that prints it as an S-expression. It just goes through great lengths to somehow have a textual representation that isn't s-expression based and then parse/print back and forth between the two. Julia also has plenty of prescribed preferred data-structure, it has a standard Array with a Vector literal [1,2,3] which is heterogeneous and it has a standard Dict type as well. So I'm seeing nothing that would be problematic if it had just gone with a Lisp syntax.