October 23, 2022
On 10/23/2022 3:43 AM, IGotD- wrote:
> Can they reuse switch? In Swift they have pattern matching but they use the switch keyword for their jack-of-all-trades switch statement. Problem with C++ (and D) is that the switch statement is fallthrough by default. In order to fix this historical mistake they need a complete new keyword.
> 
> This is something to fix in D3, remove fallthrogh by default.

Fallthrough by default was removed from D many years ago.

The awkward problem with re-using switch is that each case does not introduce a new scope. This raises all kinds of problems when using pattern matching to declare new variables.

A second awkward problem is that case statements can be placed inside nested scopes.

It's better to just leave switch as it is, and develop a new construct for pattern matching that hews to modern sensibilities.
October 23, 2022
On Sunday, 23 October 2022 at 19:28:37 UTC, Walter Bright wrote:
>
> Fallthrough by default was removed from D many years ago.

Yeah, but the break statement must still be there. I was think more like the break isn't needed at all. It should be the other way around that you have a "fallthrough" keyword instead.


October 23, 2022

On Sunday, 23 October 2022 at 01:02:16 UTC, Paul Backus wrote:

>

On Sunday, 23 October 2022 at 00:12:32 UTC, ryuukk_ wrote:
I am less optimistic about built-in sum types. The DMD frontend is not really designed to accomodate adding an entire new category of types to D's type system.

Can you elaborate on why this is case?

Would be interesting to hear Walter's opinion on built-in sum-types and obstacles in implementing them in dmd.

October 24, 2022
On 10/23/22 09:08, Imperatorn wrote:
> On Sunday, 23 October 2022 at 02:42:53 UTC, Mike Parker wrote:
>> On Sunday, 23 October 2022 at 01:02:16 UTC, Paul Backus wrote:
>>
>>> My prediction: if Walter gets bored of ImportC and decides to make pattern matching his next project, we'll get it. If he doesn't, we won't.
>>>
>>
>> Walter's primary focus right now is shoring up DIP 1000.
> 
> That's good to know. Would be great news if Dip1000 would be finalized ☀️

I don't expect it to be "finalized" very soon. It lacks expressiveness, which will be improved by small, incremental changes. Which also means it won't be stable all that soon.
October 24, 2022
On 10/23/22 21:28, Walter Bright wrote:
> On 10/23/2022 3:43 AM, IGotD- wrote:
>> Can they reuse switch? In Swift they have pattern matching but they use the switch keyword for their jack-of-all-trades switch statement. Problem with C++ (and D) is that the switch statement is fallthrough by default. In order to fix this historical mistake they need a complete new keyword.
>>
>> This is something to fix in D3, remove fallthrogh by default.
> 
> Fallthrough by default was removed from D many years ago.
> 
> The awkward problem with re-using switch is that each case does not introduce a new scope.

Actually, each case does introduce a new scope:

```d
int main(){
    int x;
    switch(x){
        case 0:
            int y;
            break;
        case 1:
            int y;
            break;
        default:
            int y;
            break;
    }
    return 0;
}
```

(You get compiler errors trying to compile that as C code, but not when you try to compile it as D code.)

https://dlang.org/spec/statement.html#switch-statement
> The ScopeStatementList introduces a new scope.

Not sure if it has always been this way (it seems my frontend that I mostly developed ~10 years ago does fail to introduce a new scope).

> This raises all kinds of problems when using pattern matching to declare new variables.
> 
> A second awkward problem is that case statements can be placed inside nested scopes.
> 
> It's better to just leave switch as it is, and develop a new construct for pattern matching that hews to modern sensibilities.

I agree with this though. Another problem is that switch cases are not ordered and are supposed to be disjoint. But for pattern matching, the semantics is usually to try each pattern in order, where patterns can overlap and you are supposed to put more specific patterns earlier.

Of course, one could think about additionally adding some pattern support to switch, where the compiler checks that all patterns are disjoint, but does not seem very nice to use. Also seems like somewhat of a hassle to implement.
October 23, 2022
On 10/23/2022 4:21 PM, Timon Gehr wrote:
> Actually, each case does introduce a new scope:

Ack, you're right. Going back and forth between C and D confuses me.


> Another problem is that switch cases are not ordered and are supposed to be disjoint. But for pattern matching, the semantics is usually to try each pattern in order, where patterns can overlap and you are supposed to put more specific patterns earlier.

Yup.


> Of course, one could think about additionally adding some pattern support to switch, where the compiler checks that all patterns are disjoint, but does not seem very nice to use. Also seems like somewhat of a hassle to implement.

The syntax of switch is old-fashioned, too. A more modern one would be:

    match (x)
    {
	0 => foo();
        3 => bar();
    }

Note the lack of need for `break`.
October 23, 2022
On 10/23/2022 4:02 PM, Timon Gehr wrote:
> I don't expect it to be "finalized" very soon. It lacks expressiveness, which will be improved by small, incremental changes.

The changes have been bug fixes. The concept has held up well.

October 24, 2022
On 10/24/22 01:42, Walter Bright wrote:
> On 10/23/2022 4:02 PM, Timon Gehr wrote:
>> I don't expect it to be "finalized" very soon. It lacks expressiveness, which will be improved by small, incremental changes.
> 
> The changes have been bug fixes. The concept has held up well.
> 

As soon as people try to use it in production they will run into some issues with expressiveness. For example, DIP1000 does not even support storing objects with different lifetimes in different fields of the same struct. (Real case that came up on Discord today.)

The underlying issue is that DIP1000 lacks a modular way to track different lifetimes. E.g., DIP100 does not allow having an array allocated on a region allocator, containing references pointing to objects allocated on a distinct region allocator with correct lifetime tracking. As soon as you store things in the array and want to get them back out, if it works at all, their lifetimes will be limited by the lifetime of the region allocator that backs the array storage, even if their own allocator actually is longer-lived.

DIP1000 is very keen to conflate different lifetimes and to cut the longer one off based on the shorter one.
October 24, 2022
On 10/24/22 01:54, Timon Gehr wrote:
> E.g., DIP100

Missed a 0 there.
October 23, 2022
On 10/23/2022 4:54 PM, Timon Gehr wrote:
> As soon as people try to use it in production they will run into some issues with expressiveness. For example, DIP1000 does not even support storing objects with different lifetimes in different fields of the same struct. (Real case that came up on Discord today.)

That's right. DIP1000 does not track lifetimes at all. It only does scoped lifetimes. Tracking requires data flow analysis, which is in the purview of @live.

> The underlying issue is that DIP1000 lacks a modular way to track different lifetimes. E.g., DIP100 does not allow having an array allocated on a region allocator, containing references pointing to objects allocated on a distinct region allocator with correct lifetime tracking. As soon as you store things in the array and want to get them back out, if it works at all, their lifetimes will be limited by the lifetime of the region allocator that backs the array storage, even if their own allocator actually is longer-lived.

That's right.


> DIP1000 is very keen to conflate different lifetimes and to cut the longer one off based on the shorter one.

Yup.

DIP1000 does not handle what you describe, and isn't designed to. However, it is still very useful for the vast bulk of cases. It's also carefully set up to be conservative, i.e. it will always err on the side of safety.

To loosen up the safety is the job of @trusted containers, similar to Rust's unsafe code blocks, because Rust's expressiveness is limited, too.