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

Walter Bright newshound2 at digitalmars.com
Tue Jul 28 22:30:22 UTC 2020


On 4/10/2020 3:27 AM, Dennis wrote:
> 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.

That's right.


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

Supporting every subset is not necessary. If you don't want toString() to be 
restrictive, do not add attributes that make it restrictive.


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

This makes the attributes added to toString ineffectual. Worse, they would be 
silently removed under your proposal. The toString's caller would think they are 
calling a pure function, may rely on it being pure, but the pure got silently 
removed.

This is not workable.


> 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, not under this DIP.

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

I suspect you're misuderstanding what the DIP proposes? The proposal does not 
remove any attributes from toString. It only adds the attributes from toString 
to the lambda.

Silently removing attributes from toString is not workable.


More information about the Digitalmars-d mailing list