Uncallable delegates

Timon Gehr timon.gehr at gmx.ch
Sat May 16 06:57:56 UTC 2026


On 5/16/26 08:31, Meta wrote:
> On Saturday, 16 May 2026 at 06:22:18 UTC, Timon Gehr wrote:
>> On 5/16/26 06:40, Meta wrote:
>>> I guess the solution is that `immutable(int* delegate())` should 
>>> become `int* delegate() immutable`.
>>
>> No.
>>
>> Here is how D catches the same problem for classes:
>>
>> ```d
>> @safe
>> class C{
>>     int* x;
>>     this(int* x)pure{ this.x=x; }
>>     int* foo(){ return x; }
>> }
>>
>> C foo()pure => new C(new int(2));
>>
>> void main(){
>>     immutable c = foo(); // ok
>>     c.foo(); // error
>> }
>> ```
>>
>> ```
>> Error: mutable method `tt.C.foo` is not callable using a `immutable` 
>> object
>> ```
>>
>>
>> However, delegates are actually not exactly > the same case as classes.
> 
> Why not? All the way down to the bedrock of CS theory, these are 
> equivalent cases.
> ...

I gave one difference in the next sentence, and your answer was "sure".

It is a well-known property of equivalence that equivalent concepts have 
equivalent properties.

>> Calling `immutable(T delegate(S))` would be sound if there were no 
>> safe way to convert mutable references to `immutable` references.
> 
> Sure, but in D, a way does exist, so it's a moot point.
> ...

Just take `shared` then.

>> The existence of `pure` factory functions means that in this case 
>> delegates do have to behave like classes. It is a global interaction.
> 
> Is your example not pretty much exactly equivalent to the fix I 
> proposed?

No. On the other hand if you had said `immutable(int* delegate())` 
should not be callable, but `immutable(int* delegate()immutable)` can 
keep being callable, then I would not have disagreed.

> What are you disagreeing with me about?

All the ways I am able to read the ambiguous sentence `immutable(int*) 
delegate())` should become `int* delegate() immutable`" are a wrong 
statement:

- immutable(int* delegate()) should not decay to `int* 
delegate()immutable` either before or after fixing the type system.

- `immutable(int* delegate())` should not be the same type as int* 
delegate()immutable either before or after fixing

- `immutable(int* delegate())` before the fix should not have the same 
meaning as `int* delegate()immutable` after the fix

Maybe you mean something else.


More information about the dip.development mailing list