New @safe rule: defensive closures
Dukc
ajieskola at gmail.com
Thu Feb 15 14:48:56 UTC 2024
On Saturday, 28 May 2022 at 14:50:39 UTC, Steven Schveighoffer
wrote:
>>
>> Good brainstorming. But I don't think it can work:
>>
>> ```D
>> void foo(ref int[5] arr)
>> { // It's not up to this function to decide where
>> // arr resides in memory. Thus we can't make a
>> // closure out of this one without breaking epected
>> // behaviour.
>> bar(arr[]);
>> }
>> ```
>>
>
> Well, we have to decide if taking a value by ref means it
> should be allocated, or if it should be scope (like DIP1000).
> If we go with the latter, then you start getting error
> messages, and we are kind of back to square one. If we go with
> the former, then any simple use of struct methods is going to
> allocate a closure.
>
> So yeah, that pretty much destroys this idea.
>
> -Steve
I'm necrobumping an old thread, because I made a discovery that I
think brings this idea back to the table.
The closures we already have suffer from the same problem I wrote
about here! Behold:
```D
int delegate(int) @safe escape1(scope int* x) @safe
{ return (int y) => *x += y;
}
int delegate(int) @safe escape2(ref int x) @safe
{ return (int y) => x += y;
}
```
These compile, but they shouldn't. They should require annotating
their parameters with `return`. Now in itself this is just a
DIP1000 bug, but consider the situation once it's fixed. If you
create a pointer to a local variable and try to return it, you
get an error, but if you create a delegate using it and return
it, you get a closure. This is a language inconsistency for no
good reason.
So we won't get rid of DIP1000 with this observation, but for
sake of consistency maybe we still should reconsider the idea
this thread is about.
More information about the Digitalmars-d
mailing list