Final type qualifier

harakim harakim at gmail.com
Sat Jul 20 06:55:27 UTC 2024


On Thursday, 18 July 2024 at 10:27:29 UTC, Quirin Schroll wrote:
> This solves two unrelated issues:
>
> - `const` class objects can’t be referred to by assignable 
> handles. It requires some trickery which probably breaks the 
> type system. Generally, if a function returns a non-mutable 
> class object, it’s not justified why the caller must be unable 
> to re-assign the variable the result is put in.
>
> - `const` delegates are broken as they don’t respect `const` 
> guarantees. As of today, `const` delegates are factually 
> `final` delegates: They can’t be reassigned, but their context 
> may change through the context pointer that’s part of the 
> delegate. If we had `final` in a new edition, old-edition 
> `const` delegates could become `final` delegates in the new 
> edition and the new edition could fix `const` delegates.

It seems to me that there are two things that const (as a 
parameter) means:
1. The caller guarantees they will not change the value
2. The callee guarantees they will not change the value

This gets really interesting with immutable, but even with 
strings, having to cast char[] to const(char)[]. If the callee is 
okay getting a char[] that is not const, const should fulfil; the 
same need, but since const means two things you have to cast. 
It's not that big of a deal, but with immutable it can be.

```
import std.stdio;

public void main()
{
     immutable(char[]) world = "world";
     bongo(world);
}


void bongo(char[] x)
{
     writeln("Bongo " ~ x);
}
```

bongo could guarantee that it does not mutate the data, but it 
doesn't want to require the caller to pass in immutable data 
because it doesn't care if the data is mutated by the caller. 
That's the caller's issue. So what should it put for the 
modifier? I feel like final is one of these cases where it's half 
of a guarantee. You could put final on bongo and it could be 
smart enough to see that it can pass immutable data or not.

This is one area that really tripped me up when I was trying to 
write multi-threaded code. I had a bunch of data that was 
initialized and then was effectively immutable from then on. 
However, it was very unintuitive that I had to copy to a new 
memory location.

Hopefully that was not too dumb. I have been wanting to say 
something about this for a while, but I'm also not an expert.


More information about the dip.ideas mailing list