← Back to context

Comment by MrJohz

2 days ago

But the point is that if you've got reflection (and an expressive base language, and a powerful enough type system, etc), you probably don't need macros. They're a heavy mallet when you almost always need a more precise tool. And the result of using macros is almost always worse than using that more precise tool - it will be harder to debug, it will play worse with tools like LSPs, it will be more complicated to read and write, it will be slower, etc.

I think macros are a necessarily evil in Rust, and I use them myself when writing Rust, but I think it's absolutely fair to judge macros harshly for being a worse form of many other language features.

No disagreement on your point, but this is a different argument than claiming that macros are an ugly hack to workaround lack of reflection.

Because Rust lacks reflection macros are used to provide some kind of ad-hoc reflection support, that much we agree... but macros are also used to provide a lot of language extensions other than reflection support. Macros in general exist to give users some ability to introduce new language features and fill in missing gaps, and yes reflection is one of those gaps. Variadics are another gap, some error handling techniques is yet another, as are domain specific languages like compile time regex! and SQL query macros.

  • But the point is that almost all of the common places where macros are used in everyday Rust could be replaced by reflection. There are exceptions like some of the ones you mention, but these are clever hacks rather than materially useful. Yes, you can write inline SQL and get it type checked, but you can also use a query builder or included strings and get the same effects but in a much less magical and brittle package.

    Macros in Rust are primarily a tool to handle missing reflection capabilities, and them enabling other code as well is basically just a side effect of that.