Discussion Thread: DIP 1032--Function pointers and Delegate Parameters...--Community Review Round 1

Dennis dkorpel at gmail.com
Fri Apr 10 10:27:37 UTC 2020


On Friday, 10 April 2020 at 09:40:12 UTC, Walter Bright wrote:
> This is still asking for (in effect) making foo() pure if the 
> delegate is pure.

The proposal is that the delegate can REMOVE attributes from 
foo() but never ADD them.

Imagine this code:
```
class MyClass
{
     @nogc @safe pure nothrow
     void toString(void delegate(const(char)[]) sink)
     {
         sink("MyClass"); // today: error! sink is not @nogc @safe 
pure nothrow
     }
}
```

This does not compile today because `sink` does not have the 
right attributes.

- your proposal says: *add* the attributes of `toString` to 
`sink`. The problem is that you now have a very restrictive sink 
function. To support impure / @gc / @system / throw sink 
functions you need an exponential amount of overloads to support 
every subset. You can't use a template either since it is a 
virtual function.

- the alternative proposal says: let `sink` *remove* attributes 
from toString if necessary. If I call toString with a sink that 
does printf, toString will lose the pure and @safe for that 
specific call. If I call toString with a sink that appends to an 
array, it will lose the @nogc for that call.

Now let's see what happens in your scenario:
```
class MyClass
{
     @safe
     void toString(void delegate(const(char)[]) sink)
     {
         writeln("bye bye pure, @nogc, nothrow");
         sink("MyClass");
     }
}
```
What if I call toString with a lambda that is pure, will it force 
toString to be pure?
No, because the sink can only temporarily *remove* attributes 
from toString, not add them.
Since toString was not pure to begin with, it does not matter 
whether sink is pure either.

I hope this makes it clearer.


More information about the Digitalmars-d mailing list