Camlp4, Template Haskell, and Rust procedural macros all serve as counterexamples to this claim.
Camlp4, Template Haskell, and Rust procedural macros all serve as counterexamples to this claim.
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.
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.
If you have to parse anything, it's not a Lisp-like macro, which is always an object arising from a production in the language.
Parsing can be hard, so he is right there too. If we take out some subset of Rust that has a significant syntax, and implement it in macros, that sounds like being up to the elbows in parsing.
let ast = parse_macro_input!(input as Foo);
Where foo is some type defined by the `syn` crate and there's one for every production in Rust's grammar. But neither are you limited to those. You can also extend or replace that grammar as you see fit, but in that case the added parsing is on you.