May 21, 2022
On 5/21/2022 5:14 PM, deadalnix wrote:
> On Saturday, 21 May 2022 at 19:46:48 UTC, Walter Bright wrote:
>> On 5/21/2022 4:54 AM, deadalnix wrote:
>>> There are holes in the foundations of the languages. These hole prevent basic things from being possible at all. For instance, containers.
>>
>>
>> Ok, can you please provide a comprehensive list of these holes?
> 
> I've done so a gazilion time, and the fact you cannot think of one is the focus problem I'm talking about.

The trouble is, posting these on the n.g. is not a good method, as the n.g. is ephemeral and no, I don't read every posting. Nobody can. When someone says "it was posted on the n.g. some time ago" there's just no way to deal with that. The n.g. is like 15 years worth of receipts thrown down the stairs into the basement to be forgotten.

A better way is to think them through, and post enhancement requests on Bugzilla. That's what it's for. Then, when someone says "what about XXX that I proposed" he can point to the bugzilla issue. If anyone has anything substantive to say about it he can attach comments to that issue.

A more formal way is to create DIPs for them.


> Just on type qualifiers:
>   - Transitivity of type qualifier doesn't play nice with template. There is no way to tell the compiler that a `const Tpl!T` actually is a `const Tpl!(const T)`. As a result, no container library is possible and ranges have serious problem when it come to qualifiers too.

This needs a lot more fleshing out about what exactly is wrong and why.

>   - delegates break constness guarantees as the type qualifier ont he context is not tracked and/or checked.

This should be a bug report in bugzilla with an example.

>   - closure break constness guarantee, as I can mutate an immutable variable visible in a closure when iterating in a loop.

This should be a bug report in bugzilla with an example.

>   - There is no way to build a shared object without breaking the type system.

That's correct. It's intended to be done with @system code. I don't know any way out of that, if you know of one, please make an enhancement request. (You can't write a storage allocator in @safe code, either.)

>   - shared is supposed to be explicit, yet all objects have a monitor - granted this one is not broken per se, but a major WTF.

The monitor idea turned out to be a bad idea. I recommend simply ignoring it.

>   - synchronized shared object cannot provide the guarantee they are supposed to because there is no adequate escape analysis.

I don't know what this means.

>   - const/immutable doesn't play nice with reference types (the qualify both the object and the reference), making the type qualifier system pretty much unworkable with OOP style code.

This needs to be a lot more specific. "doesn't play nice" is just not helpful.

> Now, don't get me wrong, some of these are hard problems. But the more we add to the pile of stuff we have, the harder they become to solve.

Thank you for writing the list.
May 21, 2022
On 5/21/2022 3:28 PM, mw wrote:
> Walter, do you hear?

What to do about people who want only bug fixes, but please include their favorite enhancement request? And what if fixing a bug requires a new or changed feature? Or who wants a recent feature backported into an old release?

There aren't obvious answers.

There's also only one of me. Anyone is free to do any of those things. That's why we're on git. We can use the help.
May 21, 2022
On 5/21/2022 5:19 PM, deadalnix wrote:
> Every one of these that qualify as a bug is in bugzilla. Some of them are more than a decade old, for instance: https://issues.dlang.org/show_bug.cgi?id=6857

I welcome any help with these.

Also, it's fine to post a list of the issues you feel are important bug are neglected. If you keep around a list of these, you can repost the list any time necessary.

BTW, 6857 is likely a breaking change. What to do about that?
May 21, 2022
On 5/21/2022 3:59 PM, Adam D Ruppe wrote:
> On Saturday, 21 May 2022 at 22:33:05 UTC, Walter Bright wrote:
>> I implemented all of the specified functionality.
> 
> Are you gonna make me dig up the original posts?
> 
> I was part of those original discussions with my use cases, one of which was specifically putting it on parameters.

You asked for a superset of what was specified.


> Not that anybody in D's leadership ever listens to me anyway.

I'm sorry about giving that impression, but I literally cannot remotely do what everyone asks me to. I'm not Microsoft with 10,000 engineers at my command. And your request *did* get eventually implemented.

For another example, `noreturn` was implemented by other than me. It turns out to be incomplete. It's now in my lap to fix it. What priority should that get?
May 22, 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?
May 22, 2022
On Saturday, 21 May 2022 at 21:24:33 UTC, Walter Bright wrote:

>
> For example, many years ago, only one person asked for User Defined Attributes (Manu). He made a compelling case for it. I implemented it. The result was a lot of pushback from the community.
>

I'll tell you why we didn't ask for them. We were brain-washed into believing that the language needed to be minimalistic, avoided feature creep, was easy for a compiler writer to implement, etc. So, we just tried to emulate them with static members in silence and pain. The compelling cases for UDAs have been demonstrated by other languages long before Manu.
May 22, 2022
On 22.05.22 03:26, Walter Bright wrote:
> On 5/21/2022 5:14 PM, deadalnix wrote:
>> On Saturday, 21 May 2022 at 19:46:48 UTC, Walter Bright wrote:
>>> On 5/21/2022 4:54 AM, deadalnix wrote:
>>>> There are holes in the foundations of the languages. These hole prevent basic things from being possible at all. For instance, containers.
>>>
>>>
>>> Ok, can you please provide a comprehensive list of these holes?
>>
>> I've done so a gazilion time, and the fact you cannot think of one is the focus problem I'm talking about.
> 
> The trouble is, posting these on the n.g. is not a good method, as the n.g. is ephemeral and no, I don't read every posting. Nobody can. When someone says "it was posted on the n.g. some time ago" there's just no way to deal with that. The n.g. is like 15 years worth of receipts thrown down the stairs into the basement to be forgotten.
> 
> A better way is to think them through, and post enhancement requests on Bugzilla. That's what it's for. Then, when someone says "what about XXX that I proposed" he can point to the bugzilla issue. If anyone has anything substantive to say about it he can attach comments to that issue.
> 
> A more formal way is to create DIPs for them.
> 
> 
>> Just on type qualifiers:
>>   - Transitivity of type qualifier doesn't play nice with template. There is no way to tell the compiler that a `const Tpl!T` actually is a `const Tpl!(const T)`. As a result, no container library is possible and ranges have serious problem when it come to qualifiers too.
> 
> This needs a lot more fleshing out about what exactly is wrong and why.
> ...

Instances of the same struct/class template are independent types without any relationship. Different types of slices (for example) are not.

>>   - delegates break constness guarantees as the type qualifier ont he context is not tracked and/or checked.
> 
> This should be a bug report in bugzilla with an example.
> ...

The bug report is 15 years old:

https://issues.dlang.org/show_bug.cgi?id=1983

Example:

```d
class C{
    int x;
    void delegate() dg;
    this(){
        dg = (){ x++; }; // mutate x
    }
}

void main(){
    const c=new C();
    auto old_x=c.x;
    c.dg(); // accepts invalid
    auto new_x=c.x;
    assert(old_x==new_x);
}
```

Solution: Properly type check the context pointer, for example it should not be possible to call a `const(void delegate())` dg because the context is const, but the function pointer accepts a mutable context.

>>   - closure break constness guarantee, as I can mutate an immutable variable visible in a closure when iterating in a loop.
> 
> This should be a bug report in bugzilla with an example.
> ...

Another 15 year old bug report:

https://issues.dlang.org/show_bug.cgi?id=2043

Example:

```d
void main(){
    int delegate()[] dgs;
    foreach(i;0..2){
        immutable int k=i;
        dgs~=()=>k;
    }
    assert(dgs[0]()==0&&dgs[1]()==1); // fails
}
```

Solution: If a delegate closes over a loop-local variable, create one context per loop iteration. (The `immutable` in the example above just demonstrates that what's going on is memory corruption, it should still work the same way if there is no `immutable`.)

> ... >
>>   - const/immutable doesn't play nice with reference types (the qualify both the object and the reference), making the type qualifier system pretty much unworkable with OOP style code.
> 
> This needs to be a lot more specific. "doesn't play nice" is just not helpful.
> ...

There is no way to declare a tail-immutable class reference.

immutable(int)* <- can rebind the reference, can't assign to value

immutable(Class) <- can't rebind the reference
Class <- can rebind the reference, can assign to value

>> Now, don't get me wrong, some of these are hard problems. But the more we add to the pile of stuff we have, the harder they become to solve.
> 
> Thank you for writing the list.

Maybe we can bump the priority on the bugzilla issues?
May 22, 2022
On Sunday, 22 May 2022 at 01:26:13 UTC, Walter Bright wrote:
> I don't read every posting. Nobody can.

I at least skim every posting and have for over a decade now. I do skip fully reading things that are obvious wastes of time though.

I'm not the only one too.

It amuses me how many things I've done that people say are impossible.

> This needs to be a lot more specific. "doesn't play nice" is just not helpful.

This has been another issue with D's const from day one. Pull request #3 was an attempt to fix it:

https://github.com/dlang/dmd/pull/3


You complain that you don't have people at your command. Well, there's plenty of people doing plenty of work.

You just keep turning us away.
May 22, 2022
On Sunday, 22 May 2022 at 01:26:13 UTC, Walter Bright wrote:
> The trouble is, posting these on the n.g. is not a good method, as the n.g. is ephemeral and no, I don't read every posting. Nobody can. When someone says "it was posted on the n.g. some time ago" there's just no way to deal with that. The n.g. is like 15 years worth of receipts thrown down the stairs into the basement to be forgotten.
>
> A better way is to think them through, and post enhancement requests on Bugzilla. That's what it's for. Then, when someone says "what about XXX that I proposed" he can point to the bugzilla issue. If anyone has anything substantive to say about it he can attach comments to that issue.
>
> A more formal way is to create DIPs for them.
>

I wrote DIP, they pretty much got ignored.

I reviewed DIP, pointing how they'd lead to the problems we have now, this got ignored too.

Honestly, never again.

>>   - delegates break constness guarantees as the type qualifier ont he context is not tracked and/or checked.
>
> This should be a bug report in bugzilla with an example.
>

https://issues.dlang.org/show_bug.cgi?id=1983

The bug is from 2008. We discussed solution 1:1 in Berlin at one of the DConf. I wrote a DIP about how to solve this. If I'm not mistaken, Timon also wrote a DIP about this.

>>   - closure break constness guarantee, as I can mutate an immutable variable visible in a closure when iterating in a loop.
>
> This should be a bug report in bugzilla with an example.
>

https://issues.dlang.org/show_bug.cgi?id=2043

Note the first one is from 2008

I think i can stop here because the point is made. All of these have long standing bug report for them. Many of these reports are 10+ years old. Several have DIPs.

The problem here isn't that people aren't reporting these, or aren't writing DIP or whatever. It is that they are told to do so, waste their time doing that and then they get named argument instead.

May 22, 2022
On Sunday, 22 May 2022 at 01:37:55 UTC, Walter Bright wrote:
>
> BTW, 6857 is likely a breaking change. What to do about that?

I would say it is not a breaking change. I write contracts so that I know when my code is broken. When the compiler fails to do so, then it is a bug in the compiler. If my code breaks because this is fixed, then that means that my code **always was broken to begin with**. I'd rather know about it.