Vision for the D language - stabilizing complexity?

deadalnix via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 7 17:56:25 PDT 2016


On Thursday, 7 July 2016 at 16:23:35 UTC, Andrew Godfrey wrote:
> So, an example to illustrate the question: In a recent thread, 
> I saw code that used an "alias parameter". I haven't seen this 
> before. Or have I? I'm not really sure, because:
> * "alias" is a keyword I've seen before.
> * type inference (which I like in general), means that maybe 
> this is the "formal" way to specify whatever it means, and 
> people usually just leave it out.
>

While I understand the sentiment, I don't think this example is a 
good one and Andrei answer only makes this more scary.

alias as in alias parameter is the exact same thing as alias in 
other situations: make this name refers to that other thing.

And here we are touching the problem: why do you expect alias to 
work in one place and do not expect it to work in other places ? 
The answer down bellow.

> I ask because I see lots of discussions that seem to be 
> proposing a change that will incrementally  increase this 
> difficulty. Over time, that would significantly change the 
> language, possibly approaching C++'s level of difficulty, which 
> I'll call "many bridges too far". And C++ seems to have given 
> up fighting this (e.g. I like the idea of the C++ "uniform 
> initialization" and "initializer list" features, but the way 
> their syntax interacts with old-school syntax is frustrating.)
>

While this very true, it is clear that most D's complexity 
doesn't come from there. D's complexity come for the most part 
from things being completely unprincipled and lack of vision.

Let me get back to your alias example. alias does one thing: give 
a new name to some existing thing. For instance, after doing:

alias foo = bar;

I can use foo as an identifier and it will refer to bar.

Now as to parameters. Parameters are like declarations, but the 
value is provided in the form of an argument. For instance:

void foo(int a) {} // a is a parameter.
foo(3); // 3 is an argument.

In that specific instance, we conclude that within foo, it is as 
if we declared int a = 3 (in that specific case).

The concept of alias and the concept of parameter/argument are 
completely orthogonal, and therefore, there should be no 
expectation that anything special is going on. So, in

template Foo(alias A) {}
Foo!bar;

Things should be as if, for this specific instance, within Foo, 
we specified alias A = bar;

Except that it is not the case. D fucks up orthogonality 
everytime it has the opportunity. As a result, there is a ton of 
useless knowledge that has to be accumulated. For instance :

alias A = int; // Nope
template Foo(alias A) {}
Foo!int; // OK !

In general, things are so unprincipled that there is no 
expectation that they are anymore. For instance, you'd expect that

template Foo(T...) {}

would take a variadic number of type as arguments, while

template Foo(alias T...) {}

would take a variadic number of aliases. But no, 1 take a 
variadic number of aliases and 2/ is invalid. So now we've 
created a situation where it is now impossible to define 
variadic, alias and parameter/argument as 3 simple, separate 
things, but as a whole blob of arbitrary decisions.

This turtles down the the most simple thing:

enum E { A = 1, B = 2 }
E bazinga = A | B;
final switch (bazinga) { case A: ... case B: ... } // Enjoy !

And so on, @safe only mean safe if you do not do this and that, 
DIP25 is ready to add a new pack of brick to the already tanking 
Jenga tower. Shared doesn't work and Walter promote use of 
undefined behavior to work around them.

In fact, when it comes to news feature, more than the added 
complexity of the feature itself, it it's interaction with 
existing madness that worries me. Not only there is an explosion 
of special cases that is completely untractable, but it also 
cement the existing madness.


More information about the Digitalmars-d mailing list