This is getting to be a big problem with Rust. The language, or maybe its community, encourages cutesy stuff like this. Remember "Diesel", the Rust compiler for SQL, from a few days ago? Just because you can doesn't mean you should. Too much fancy template stuff is being baked into the low level libraries. This may not end well.
C++ went down this road. The template system turned out to be more powerful than intended. Then people started writing cool stuff as fancy templates. Then the C++ committee added features to support the fancy templates better. Overly elaborate templates damaged C++; nobody could figure out what was going on. Use of C++ for new work declined.
All of this comes from smart people with good intentions. But when there's too much of this stuff, the mental load required to keep up with all of it becomes excessive. Especially if it changes a lot.
Rust generics are deliberately less expressive than C++ templates, in that they're strongly typed. That's why we get so many complaints from C++ and D developers that you can't do certain things. But Rust sticks with its strongly-typed generics, because Rust has always tried hard to strike a balance between code expressivity and maintainability.
This is a terrible example if you want to prove that point, anyway. This 6502 assembler is obviously a total abuse of the system, and nobody will deploy it to production. It's a neat hack, and that's all. Nobody would use an obfuscated quine written in Go to argue that Go is unreadable. This is exactly analogous.
Finally, Diesel is just an ORM. It uses exactly enough features to be an ORM; the only "problem" with it is that it's an ORM.
In C++, you get this damage from for example operator overload abuse (ok for math, not many other defensible uses), template abuse (ok in moderation), ninja exceptions and inheritance (especially multiple inheritance, ugh).
Anyways, if Rust proves to be a feasible workhorse building medium/large systems with bigger teams, it does sound interesting to me. Especially catching concurrency issues at compile time.
I just hope it won't ever become another C++.
By the way, Rust has no "template abuse", "ninja exceptions", or "inheritance".
Rust might eventually become the new industry standard. That'd be a clear improvement for sure.
But we'll see what happens. Hopefully there'll be no Rust committees at least.
It is not the ORM library or the 6502 Assembler.
It is the library written by the clever guy on the third floor from blue team, for the new product being developed at Corpo X.
However I also have seen lots of convoluted code, exactly because such expressiveness is missing from the language.
For example, JVM bytecode manipulation or use of external code generators.
That's the operating point here. Leave out expressivity, and tons of programmers write convoluted code. Leave it in, and a couple of clever people use it in an over-clever way.
In what sense are Rust macros "strongly-typed"? D and C++ templates are also strongly typed, just like the rest of the language.
[1]: https://github.com/Manishearth/rust-clippy/wiki#cyclomatic_c...
And it is even easier to write useful, beautiful things with macros, which are really easy to fix and debug.
Curious, with your LISP and ML background, what method or methods do you use to ensure your macros are correct and easy to debug?
Macros must be staged - similarly to a good practice of not having too big functions, macros also must be small, and must transform code in small steps, with more macros further breaking the result down. Ideally, each macro must be a trivial rewrite doing only one small thing.
Another trick is to have a bunch of macros that would inject debugging output when enabled. Wrap every macro definition body in such a macro, and, with debugging turned on (can be selective), both source and output would be displayed. Another macro can be used to inject debugging info into a generated code.
I usually start writing macros the other way around - not from a code I'd like to see generated, but from a final form. Once I find the code with macros passable, I'll start implementing the macros, in small steps.
Same applies to a DSL design in general - first I write a code I want to see, and only then I fill in an implementation.
LISP's FOR macro got so clever that LISP programmers do everything they can to avoid using it
> C++ went down this road.
Also a big problem in the Haskell community. Trying to prove all sorts of complicated properties in a simple type system leads to overcomplicated design.
I don't think I'm against static code generation. But it incurs mental overhead. If you do it using a language which wasn't designed for that, much more so.
My corresponding counterpoint is that you can write an obfuscated code in any language, no exception---probably a side-effect of Turing-completeness. If people has a general dislike towards too much magic and magic can be replaced with science^W saner alternatives there is no problem. The problem arises when you have to rely on magic for the certain class of tasks; it's no doubt that C++ (even the modern one) has this problem, but I think it is too early to claim that Rust has the same symptom.
I haven't seen any examples of this happening in actual code. Sure, you have lots of toy things but that's just stuff people do for fun.
And as was adequately explained in that thread, ORM is an existing pattern from other languages that people like using. It's got some nifty benefits to it; so while it's not what you'd usually do it's not an overcomplication. Like Patrick said, its only "problem" is that it's an ORM.
> Overly elaborate templates damaged C++; nobody could figure out what was going on. Use of C++ for new work declined.
This happens because C++ templates aren't typechecked, so working with them requires you to understand their internals to some degree ("what kind of type does this expect?"). Rust generics are typesafe. Rust macros aren't, but they're not encouraged as much as generics/templates are so you don't see much convoluted things except as fun experiments (who doesn't want to write a brainfuck interpreter in rust macros?). People understand that macros will give substandard error traces and mostly only use them for quick and straightforward deduping of code.