C++ pattern matching is coming

Timon Gehr timon.gehr at gmx.ch
Mon Oct 24 01:50:54 UTC 2022


On 24.10.22 02:29, Walter Bright wrote:
> 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 kind of does a bit with return annotations:

```d
int* foo(return scope int* x)@safe{
     auto y=x;
     int t;
     auto z=&t;
     return y; // ok, but can't return z
}
```

> It only does scoped lifetimes.

My use cases with storing references in structs and region allocators 
can be dealt with with scoped lifetimes only, but they still do not work 
with DIP1000.

In any case, I'd also consider that lifetime tracking, it's just not 
very precise. The main problem though is lack of modularity. In the 
example above, `y` and `z` are different, and the compiler understands 
that they are different within that one function, but there is no way to 
preserve that difference when passing both of them though a function 
further down the stack at the same time.

> Tracking requires data flow analysis, which is in the 
> purview of @live.
> ...

I guess my issue here is that @live, while it may use some methods that 
may be helpful in another context, does not enable any of the use cases 
I described either. It does not make @safe any safer and it also does 
not make DIP1000 any more modular.

>> 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.

I agree that it is quite useful for some cases. It just does not seem to 
offer all that much yet in terms of actually enabling safe manual memory 
management for the entire application.

> 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.

Yes, it is also limited (additional safety guarantees always come with 
some limitations), but it can do everything I brought up above. 
Furthermore, the unsafe blocks can usually be hidden away in libraries 
with expressive interfaces that are able to distinguish distinct 
lifetimes pretty well.


More information about the Digitalmars-d mailing list