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