top | item 28339212

(no title)

dfranke | 4 years ago

> [Lisp macros] by their nature would be hard to implement properly in a language without turning it into a dialect of Lisp.

Camlp4, Template Haskell, and Rust procedural macros all serve as counterexamples to this claim.

discuss

order

throwaway17_17|4 years ago

To the best of my knowledge, and I could be wrong, none of those languages/extensions allow for run time generation of code. I think there is a great deal of semantic difference between compile time code execution that enables syntax manipulation and the full scope of Lisp macros. I’m not making a judgment about the value of such capabilities, but I really think they make for distinct expressability classes.

dfranke|4 years ago

Common Lisp macros are precisely "compile time code execution that enables syntax manipulation". If by "runtime generation of code" you mean to include executing that code after it's been generated, that's not macros, that's `eval`.

Just as use of `eval` tends to be discouraged in Lisp land, it's not something that a Haskell or Rust programmer would often reach for. But in Haskell, if you really want it, GHC has an API and you can have the whole power of the compiler available to you at runtime. This isn't really a language feature per se, it's literally just linking in the whole compiler and calling it like an ordinary library. I'm not aware of anything similar to that in Rust but I haven't really looked. However, if you're only trying to generate code and not JIT-compile or execute it, the same Rust crates that support compile-time AST manipulation (like `syn` and `quote`) can equally well be used at runtime.

kazinator|4 years ago

Are you saying that they were easy to implement, and that it was done properly?

dfranke|4 years ago

Implementing a modern, production-quality compiler is not easy as a baseline, but nothing in the design of OCaml, Haskell, or Rust adds any significant obstacles, relative to Common Lisp, to supporting this feature. Slinging an AST around and dropping it into a quasiquoted template is a well-understood problem. The simplicity of Lisp's syntax is not a prerequisite and hasn't been since the parsing techniques that were developed in the 1970s.

Done properly? I can't speak to camlp4, but at least in the case of Haskell and Rust, certainly. Incidentally I just had my first occasion to write a Rust procedural macro last weekend. I had a significantly complex transformation written and working in half a day, learning curve included, and I found it all pretty frictionless.