top | item 46986354

(no title)

badsectoracula | 19 days ago

One feature of D that i really wish other languages would adopt (not sure about Rust but i also think it lacks it, though if it has it to a similar extent as D it might be the reason i check it again more seriously) is the metaprogramming and compile-time code evaluation features it has (IIRC you can use most of the language during compile time as it runs in a bytecode VM), down to even having functions that generate source code which is then treated as part of the compilation process.

Of course you can make codegen as part of your build process with any language, but that can be kludgy (and often limited to a single project).

discuss

order

skocznymroczny|19 days ago

Arguably, most of the metaprogramming in D is done with templates and it comes with all the flaws of templates in C++. The error messages are long and it's hard to decipher what exactly went wrong (static asserts help a lot for this, when they actually exist). IDE support is non-existent after a certain point because IDE can't reason about code that doesn't exist yet. And code gets less self-documenting because it's all Output(T,U) foo(T, U)(T t, U u) and even the official samples use auto everywhere because it's hard to get the actual output types.

srean|19 days ago

It is quite ridiculous to place C++ metaprogramming and D's. For one in D it's the same language and one can choose whether to execute compile time constant parts at compile time or run time. In C++ it's a completely different language that was bolted on. C++ did adopt compile time constant expressions from D though.

arcadia_leak|19 days ago

I'd say D's template error messages are much better than C++'s, because D prints the instantiation stack with exact locations in the code and the whole message is just more concise. In C++, it just prints a bunch of gibberish, and you're basically left guessing.

schveiguy|19 days ago

No, templates are only needed to introduce new symbols. And D templates are vastly superior to C++. D's superpowers are CTFE, static if, and static foreach.

auto is used as a return type because it's easy, and in some cases because the type is defined internally in the function and can't be named.

You would not like the code that uses auto everywhere if you had to type everything out, think range wrappers that are 5 levels deep.

ameliaquining|19 days ago

Rust has procedural macros, which turn out to be a good-enough substitute for real compile-time reflection for surprisingly many use cases, though nowhere near all of them. (In particular, Serde, the universally-adopted framework/library for serializing and deserializing arbitrary data types, is a third-party library powered by procedural macros.)

Real compile-time reflection is in the works; the very earliest stages of a prototype implementation were released to the nightly channel last month (https://github.com/rust-lang/rust/pull/146923), and the project has proposed (and is likely to adopt) the goal of completing that prototype implementation this year (https://rust-lang.github.io/rust-project-goals/2026/reflecti...), though it most likely will not reach the stable channel until later than that, since there are a whole lot of complicated design questions that have to be considered very carefully.

debugnik|18 days ago

"Powered by" is an understatement, Serde would be unusable without procedural macros. Deserializers use a ridiculously verbose visitor pattern that's completely unnecessary in a language with move semantics, it should have been a recursive descent API.

Using serde_json to accurately model existing JSON schemas is a pain because of it.

I personally find third-party deriving macros in Rust too clunky to use as soon as you need extra attributes.