The magic behind foreach (was: Re: Descent 0.5.3 released)
Ary Borenszweig
ary at esperanto.org.ar
Thu Jan 22 15:52:25 PST 2009
Bill Baxter wrote:
> On Fri, Jan 23, 2009 at 8:10 AM, Christopher Wright <dhasenan at gmail.com> wrote:
>> Ary Borenszweig wrote:
>>> If the compiler can transform a "foreach" into an opApply call, passing
>>> the foreach body and converting breaks to "return 1" statements... can't
>>> opApply be specified as:
>>>
>>> int opApply(void delegate(ref uint) dg) { // note: delegate returns void
>>> }
>>>
>>> and the compiler transforms the opApply signature to the one that's used
>>> now, plus converting each dg call to a call and a check of return value !=
>>> 0 and return 1 in that case?
>> This only fails if you wish to take a particular action when the calling
>> code breaks out of iteration. This is not such a large use case that I think
>> it worth preserving.
Why do you mean by "fails"? The compiler transforms the foreach's body,
it can transform the opApply's body.
>
> It's not?
>
> foreach(i; things) {
> if (i==a) continue;
> if (i==b) break;
> if (i==d) return;
> if (i==c) goto somewhere;
> }
>
> Those are all fairly common things to do from inside the 'dg' call.
> The int is how the compiler distinguishes which case got you out of
> the dg.
>
> --bb
Aaaah... Now I see what's the return value of opApply for. So I tried
your code:
(just the relevant piece)
---
int main(char[][] args) {
int a = 1, b = 2, c = 3, d = 4;
Foo foo = new Foo();
foreach(i; foo) {
if (i==a) continue;
if (i==b) break;
if (i==d) return;
if (i==c) goto somewhere;
}
somewhere:
return 0;
}
---
and DMD spits out this:
---
int main(char[][] args) {
int a = 1, b = 2, c = 3, d = 4;
Foo foo = new Foo;
switch(foo.opApply(delegate (uint __applyArg0) {
{
uint i = __applyArg0;
if(i == cast(uint) a)
return 0;
if(i == cast(uint) b)
return 1;
if(i == cast(uint) d)
return 2;
if(i == cast(uint) c)
return 3;
}
return 0;
} )) {
default:
break;
case 2:
return;
case 3:
goto somewhere;
}
somewhere:
return 0;
}
---
Intersting. The compiler (Walter?) is being smart here. :-)
More information about the Digitalmars-d
mailing list