converting expression to delegate works only for variadic array?

Steven Schveighoffer schveiguy at yahoo.com
Fri Jun 1 14:30:22 UTC 2018


On 6/1/18 10:08 AM, Gopan wrote:
> Hi,
> I created a test application (test.d) to learn delegates.
> 
> import core.stdc.stdio;
> 
> void Multi (int delegate()[] args ...)
> {
>      foreach (exp; args)
>      printf ("%d, ", exp() );
>      printf ("\n");
> }
> 
> void Single (int delegate() exp)
> {
>      printf ("%d\n", exp());
> }
> 
> void main()
> {
>      int x = 5;
>      Multi( {return 1;}, {return 2+x;} ); // outputs 1, 7 as expected.
>      Multi( 1, 2+x); // same as above.  produces same output.
>      Multi( 3+x ); //produces output 8.
>      Single( { return 3+x; } ); //produces output 8
>      Single( 3+x ); // COMPILATION ERROR pasted towards bottom.
>          // Good. But why does Multi(2+x) not have this issue?
> 
>      int delegate() exp = { return 4+x; };
>      printf("%d\n", exp() );
> }
> 
> test.d(22): Error: function test.Single(int delegate() exp) is not 
> callable using argument types (int)
> test.d(22):        cannot pass argument 3 + x of type int to parameter 
> int delegate() exp
> make: *** [test.obj] Error 1
> 
> I am happy with the statement Single(3+x) producing this compilation error.
> 
> But why Multi(3+x) doesn't have this issue?  For that, it is allowed as 
> per 'Section 19.16.3.4 Lazy Variadic Functions' of the article 
> https://dlang.org/spec/function.html#closures.
> 
> What is the rationale behind not allowing it for the non-array signature?

These things were decided long ago, when D was just D1, and D2 didn't 
even exist.

I think the rationale might go like this:

1. We have a lazy parameter, lazy int, which translates into a delegate 
automatically.
2. Cool, we need a way to do this with variadics. But what does lazy 
int[]... mean? Does it mean an array that's lazily calculated, or does 
it mean an array of lazily calculated parameters?
3. lazy int[]... was decided to mean a lazily calculated int array (the 
whole array is created whenever it is used).
4. int delegate()[]... was decided to mean an array of lazily passed ints.

IMO, lazy X and X delegate() should be interchangeable API-wise and 
exactly the same. You should be able to call either one with an X or a 
delegate. This makes the most sense and is the most useful.

-Steve


More information about the Digitalmars-d-learn mailing list