Why is D unpopular, redux.

Timon Gehr timon.gehr at gmx.ch
Sun May 22 09:39:13 UTC 2022


On 21.05.22 15:00, deadalnix wrote:
> On Saturday, 21 May 2022 at 11:39:06 UTC, Timon Gehr wrote:
>> Yes, probably needs a DIP. Seems somewhat tricky to get just right. 
>> The mechanism should be simple and should e.g. allow the wrapping of a 
>> built-in slice within a templated struct with the same typing behavior.
>>
>> A pretty simple feature that seems to do the job would be something like:
>>
>> ```d
>> @structuralSubtyping
>> struct Slice(T){
>>     T[] payload;
>> }
>> ```
>>
>> Then whenever you need to evaluate a subtyping relationship between 
>> multiple instantiations of the same @structural-annotated templated 
>> type, you check that the field layout matches (including field names) 
>> and that all field types are subtypes of their new type.
>>
>> There should be a way to do custom introspection (subtype constraints).
>>
>> ```d
>> @structuralSubtyping!condition
>> struct Slice(T){
>>     T[] payload;
>> }
>> ```
>>
>> Where "condition" is passed both instantiated types with full 
>> qualifiers and can do additional checks to possibly maintain typing 
>> invariants that are not tracked by D's type system alone.
>>
>> There should also be an unsafe escape hatch to exclude certain members 
>> from the automated field layout checks, but maybe void* and void[n] 
>> are good enough for this.
>>
>> Finally, the magic "strip qualifiers when passing a slice to a 
>> function" rule should be applied to template types with 
>> `@structuralSubtyping`.
> 
> While this would allow to do the container thing, I do not believe this 
> is the right way to go at it.

Well, it works, solves the problem, and most likely has a simple enough 
implementation.

> It has an DIP "do the thing" flavor to it. 
> I think not being able to do containers is a symptom of a missing piece 
> in the type system, most notably type qualifier.
> 
> As far as I can tell, what's needed is a for of generics, at least for 
> type qualifiers.
> ...

Of course, that was also on my list of features I wish for:
https://forum.dlang.org/post/sk4v9b$2apt$1@digitalmars.com

Let's say we get generics only for type qualifiers, then you can maybe 
do something like:

struct Slice[qualifier q](T: q(T)){
     q(T)[] payload;
}

But now, even if you can figure out what new sub-language of generic 
parameter annotations you need to fully capture possible subtyping 
relationships between different generic instances, this still does not 
solve the problem that there is magic typing behavior:

class A{}
class B:A{}

static assert(is(const(B)[]:const(A)[]));

static assert(is(Slice!(const(B)):Slice!(const(A))));

I.e., it would need to be generics all the way down, and to get the 
subtyping behavior you want, you'd need annotations to distinguish cases 
like:

```d
struct S[T]{
     T[][] payload;
}

struct S[T]{
     const(T)[] payload;
}

struct S[T]{
     T[] payload;
}

struct S[T]{
     T payload;
}
```

That's something of an endeavor if you want to aim for completeness, so 
I think something like @structuralSubtyping is looking pretty good from 
a usability perspective even if you have generics.

> I don't pretend to have all the solutions, and I'm sure that the 
> combined talent of the community can sort this out if, and that's a big 
> if, we are willing to actually focus on what really matters here.

Does this even qualify as "really matters"? Why is this even blocking 
Phobos containers?


More information about the Digitalmars-d mailing list