DMD 0.166 release

Ivan Senji ivan.senji_REMOVE_ at _THIS__gmail.com
Fri Sep 1 16:54:21 PDT 2006


Sean Kelly wrote:
> 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.
> 
> It may be that delegates should be implicitly convertible to lazy 
> expressions with the same signature.  Thus:

Maybe, that is what I expected it would do in the first place (it's too 
late to think now :))

> 
>     void fn( lazy int x );
> 
> Should accept both:
> 
>     fn( i++ );
> 
> and
> 
>     fn( { return i++; } );
> 
> Currently, they only accept the former.

Except in a strange (but documented) feature that variadic arguments are 
implicitly converted to delegates (used in my reply to myself).



More information about the Digitalmars-d-announce mailing list