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