What is the difference between "delegate()" and "lazy delegate()" ?

Ali Çehreli acehreli at yahoo.com
Sat Jan 2 18:56:03 UTC 2021


On 1/2/21 4:29 AM, Marcone wrote:
> Why "lazy delegate()" need two parentheses to execute function?

lazy automatically makes a delegate that returns the type of the parameter:

void bar(lazy int i) {
   writeln(i);  // i is a delegate called automatically
}

Strangely, the delegateness leaks out and i() works as well:

   writeln(i());  // WAT?

I agree with you that double parenthesis is strange for a lazy delegate 
but the fact above explains to me what is happening: The first set is 
for lazy's delegate to get the actual delegate, and the second set is 
used for calling the actual delegate.

I agree that it feels wrong that d(3) is not allowed below even though 
'i' alone is allowed above. I vaguely remember issues around delegates 
where it wouldn't be clear whether one is referring to the delegate 
itself with 'd' or whether calling the delegate as d() but without the 
parenthesis.

Yeah, that's it: If we were allowed to call delegates without the 
optional parenthesis, we would never be allowed to refer to a delegate 
itself:

   typeof(d)    // <-- Is that the type of the delegate or what it returns?

So, the double parenthesis are needed for the fact that delegates cannot 
be called without optional parenthesis. (I think. :) )

Here is a program that I played with before writing this:

import std.stdio;
import core.thread;
import std.random;

void foo(lazy int delegate(int) d) {
   if (dice(50, 50)) {
     writeln("Using the delegate");
     d()(3);    // d(3) should work as well
   }
}

int delegate(int) delegateMaker(int multiplier) {
   writeln("Waiting for expensive delegate making operation...");
   Thread.sleep(2.seconds);

   return (int i) {
     writeln("Delegate called");
     return multiplier * i;
   };
}

void main(string[] args) {
   foo(delegateMaker(2));
}

Ali


More information about the Digitalmars-d-learn mailing list