DMD 0.166 release

Chris Nicholson-Sauls ibisbasenji at gmail.com
Sat Sep 2 01:18:31 PDT 2006


Ivan Senji wrote:
> Chris Nicholson-Sauls wrote:
> 
>>
>>
>> Ivan Senji wrote:
>>
>>> Walter Bright wrote:
>>>
>>>> The implicit conversion to delegate just broke too much. Instead, 
>>>> I'm trying out Tom S.'s suggestion of using a 'lazy' parameter 
>>>> storage class.
>>>>
>>>> http://www.digitalmars.com/d/changelog.html
>>>
>>>
>>>
>>> Hmm, I am afraid I have to admit I'm a little bit puzzled by this 
>>> lazy thing.
>>>
>>> Let's say we have:
>>>
>>> void dotimes(int count, lazy void exp)
>>> {
>>>   for (int i = 0; i < count; i++)
>>>   {
>>>     exp();
>>>   }
>>> }
>>>
>>> and I can call it like this:
>>>
>>> int x;
>>> dotimes(5, x++);
>>>
>>> And it works as expected and x end up being 5.
>>>
>>> But shouldn't I also be allowed to pass in a delegate of the 
>>> appropriate type
>>>
>>> dotimes(5, {writefln(x); x++;});
>>>
>>> A funny thing happens: nothing. The loop in dotimes does get executed 
>>> 5 times but delegate passed in isn't called?
>>>
>>>
>>
>> This is because anonymous delegates are themselves expressions, and so 
>> your 'exp()' just evaluates to the delegate itself -- it does not 
>> invoke it.  However, to achieve what you were trying to do, just make 
>> use of parentheses and the comma operator.  Also, you may provide an 
>> overload that takes a lazy delegate.  Here is my own test program, 
>> which worked without issue:
> 
> 
> Hmm, there is something about this lazy stuff that is troubling me and 
> I'm not exactly sure what it is and if I can explain it:
> 
> so it is x++ vs {writefln(x); x++;}
> 
> The first one is an expression that looks like it is executed at call 
> site but it isn't because that parameter is declared to be lazy. It is 
> executed inside dotimes. That is ok.
> 
> The second is a block of statements, actually it is a void delegate. It 
> isn't executed at call site so it also will not be executed in dotimes.
> To make it be executed in dotimes I have to make it into something that 
> looks like it is being executed: for example: {writefln(x); x++;}()
> 
> And this is when thing begin to suck (unless I am missing something?).
> 
> So if I had
> dotimes(5, x++);
> 
> and now if I want it to do 5 times somethin a bit more than just x++ i 
> cannot just write:
> dotimes(5, {writefln(); x++;});
> 
> And now a completly different function is called (one taking void 
> delegate() as argument), to get it to call the lazy function I have to 
> change to type from void delegate() to void by pretending to be calling 
> the delegate.
> 
> So is there a point to having lazy, I could only have written dotimes 
> that takes void delegate() an write this:
> 
> dotimes(5, {x++;});  and   dotimes(5, {writefln(); x++;} );
> 
> vs
> 
> dotimes(5, x++);     and   dotimes(5, {writefln(); x++;}() );
> 
> And now (while writing) I finally figure out what was troubling me: each 
> of these approaches has a pretty case and an ugly case, the two pretty 
> cases being:
> 
> dotimes(5, x++);  and   dotimes(5, {writefln(); x++;} );
> 
> But to get that to work 2 different methods are needed.
> 
> Don't feel the need to reply to this incoherent post :D , it is just 
> some of my thoughts about lazy.
> 
> Although now I understand what is happening and why, this is still 
> troubling me.

Or... just put parentheses around it instead of braces, and use commas instead of 
semicolons, like I did.  That works without having to do any extra work at all.  (Although 
your typesafe variadic delegate parameter trick is pretty interesting, too.)

dotimes(5, x++);
dotimes(5, (writefln(x), x++));

-- Chris Nicholson-Sauls



More information about the Digitalmars-d-announce mailing list