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

Steven Schveighoffer schveiguy at gmail.com
Tue Apr 7 21:36:13 UTC 2020


On 4/6/20 5:11 PM, Walter Bright wrote:
> On 4/6/2020 5:46 AM, Steven Schveighoffer wrote:
>> i.e., if both are pure, the function is pure. If either one is not 
>> pure, the function is not pure.
>>
>> if both are @nogc, the function is considered @nogc. If either is not 
>> @nogc, the function is not considered @nogc.
> 
> That's more or less what the DIP proposes. The delegate parameter 
> defaults to being at least as restrictive as the function it is declared 
> in. The delegate parameter can be made more restrictive by adding 
> attributes to it directly.

No, the function can't be called from such a caller that creates a delegate.

For example, if you have:

void foo(void delegate() dg) { dg(); }

Let's say I'm in a @nogc function, and I want foo to call my local 
lambda @nogc delegate. Sure, I can pass in a delegate that is @nogc to 
this function, because of the implicit cast allowed. but I can't 
actually call the function from that context! It becomes useless. Then I 
need 2^n copies of foo, one for each possible set of attributes.

This is why we use templates for such things, but really, it would make 
a whole lot more sense to avoid generating identical code for 2^n calls 
(which is what a template of that kind would do), and you would get for 
free the fact that the delegate's attributes match the function call's 
attributes.

> To make the delegate parameter less restrictive, it would need to be 
> declared using an alias for the type, as shown in the DIP.
> 
> The point of this is so that the function can call the delegate, which 
> is far and away the usual use case. The unusual use case is storing the 
> delegate somewhere else for someone else to call.

First, I disagree that it's unusual to store delegates. Far and away D 
code that calls a function you pass in uses aliases, which require 
templates, which infer all attributes anyway. But you have to use a 
delegate when you need to store it somewhere for later.

Second, I understand that there are ways to get this behavior, but it 
seems like if you are going to solve the "delegates that are called 
presently" problem (i.e. the lazy issue), you would be better to solve 
it in a way that doesn't require dozens of boilerplate repetition.

> The DIP does not propose that the delegate parameter infer its 
> attributes based on the function's body. To implement that would require 
> an iterative approach, and that is not worth the complexity.

That's not what's being discussed. There is no requirement to infer 
anything from the function body. All that is required is to examine the 
set of attributes defined on both the function and the delegate, and 
logic-or them (or logic-and them, I don't really know).

-Steve


More information about the Digitalmars-d mailing list