Why is D unpopular?

FeepingCreature feepingcreature at gmail.com
Mon May 2 06:15:32 UTC 2022


On Monday, 2 May 2022 at 01:42:19 UTC, Walter Bright wrote:
> On 5/1/2022 1:39 PM, Max Samukha wrote:
>> I don't quite understand why you insist on native code. Do 
>> compilers to bytecode count? There used to be a language 
>> called Nemerle (https://en.wikipedia.org/wiki/Nemerle), which 
>> had been mentioned on these forums many times, long before D 
>> got CTFE. The earliest mention I found is 
>> https://forum.dlang.org/post/ca56h1$2k4h$1@digitaldaemon.com. 
>> It had very powerful macros, which could be used as compile 
>> time functions, AST macros, and whatnot. The language is now 
>> dead because it was too good for humans.
>
> Nemerle targeted C#'s bytecode system. I.e. it's an interpreter.
>
> A language designed for interpretation does not distinguish 
> between compile time and run time. While the program is 
> executing, it can generate more code, which the interpreter 
> executes. If the language is successful, it'll often get a 
> native code generator to speed it up. The compiler is part of 
> the runtime of the language.
>
> A language designed for native compilation draws a hard 
> distinction between compile time and run time. You'll see this 
> in the grammar for the language, in the form of a 
> constant-expression for compile time, and just expression for 
> run time. The constant-expression does constant folding at 
> compile time. The runtime does not include a compiler.
>
> D is the first language I know of, designed for native 
> compilation, with constant-expressions, that extended the 
> evaluation of constant-expressions with the ability to execute 
> functions at compile time. There's no compiler in the runtime. 
> D does not support compiling code at runtime.
>
> To clarify, if the runtime of a language includes a compiler, 
> that is in the interpreted class of languages (even if they jit 
> to native code), and it is not an example of what D's CTFE is 
> doing. Lisp, Java, C# and apparently Nemerle fall into this 
> category.
>
> To show D is not the first, I request an example of a language 
> designed for native compilation, that does not include a 
> compiler in the runtime, that has constant-expressions in the 
> grammar that must be computed at compile time and can execute 
> ordinary functions at compile time.
>
> C++ came closest to the mark with its Turing-complete templates.

This is an odd division to me. The way I do it in my lang is to 
just treat compiler runtime as a separate compilation target. 
Interpretation, code generation, it's all backend concern. But 
that still gives me the sort of "run program code at compiletime" 
capability that I think Nemerle aims at (though I've never used 
it), without any interpretation, just by targeting parts of the 
program at a backend that can be loaded back during the 
compilation run. And I think that's fundamentally a cleaner model 
than CTFE, because it doesn't rely on, in effect, embedding an 
entirely separate codepath for constant folding that reimplements 
deep parts of the compiler; instead, there is only one path 
through the compiler, and the split happens cleanly at the 
back-end ... and one backend just happens to be invoked by the 
compiler itself during compilation to get a function pointer to 
directly call.

One problem of doing it this way is that it makes `static if` 
very awkward. You're trying to evaluate an expression, but you 
want to access local "compiletime variables" - so you need to 
compile the expression being tested in an odd context where it 
lives in a function, "but not really" - any access to local 
variables triggers a special error, because the expression is 
really semantically at something like toplevel, it just 
syntactically lives inside a function. That's why for now, I just 
use constant folding like D for `static if`. (Also, I'm dog slow 
and I'm trying to limit the amount of macro compilation 
roundtrips. Gonna switch to an *interpreter* backend some time - 
for a *speedup.* LLVM makes good code, but its performance is 
painful.)

But I still think this is fundamentally the right way to think 
about CTFE. The compiler runtime is just a backend target, and 
because the compiler is a library, the macro can just recurse 
back into the compiler for parsing and helper functions. It's 
elegant, it gets native performance and complete language support 
"for free", and most importantly, it did not require much effort 
to implement.


More information about the Digitalmars-d mailing list