On 2011-10-12 22:56, Nick Sabalausky wrote:
"Jacob Carlborg"<[email protected]> wrote in message
news:[email protected]...
When this delegate is called you want to both be able to just return from
the delegate but also return from "foo".
iterate(1, 10 ; int a)
{
if (a == 2)
yield; // soft return, just returns from the delegate
else if (a == 4)
return; // hard return, return from both the delegate and the
function that called the delegate
}
Currently we only have "soft" returns from delegates.
Better (IMHO):
void foo()
{
iterate(int a; 1, 10)
{
if (a == 2)
continue; // return from just the delegate
else if (a == 4)
break; // return from both delegate and iterate
else if (a == 6)
return; // return from the delegate, iterate, and foo
}
}
That's actually how it works in Ruby as well. Ruby also has both lambdas
and blocks, the only difference between them is that you can't
return/break from a lambda but you can from a block (I hope I got this
right).
This answer to a stack overflow question explains how it works in Ruby:
http://stackoverflow.com/questions/1402757/how-to-break-out-from-a-ruby-block#answer-1402764
Ie, same syntax and semantics as foreach. Also, a couple new things that
foreach doesn't have to deal with:
auto x = map(i; 1, 10)
{
//continue; // Error: map's dg can't return void
continue i*2; // OK
}
assert(x == [2, 4, 6, etc...]); // Conventiently ignoring ranges just for
the sake of illustration
Of course, maybe it would be better to require "yield" in such a case (and
maybe make "yield" synonymous with "continue" for void delegates?), but
there's a lot of resistance against new keywords.
Yeah, I know that.
And, one last thing to take care of:
auto x = iterate(i; 1, 10)
{
if(i == 4)
{
//break; // Error: need a return value
break i*2; // OK
}
}
assert(x == 8);
Yeah, assuming "iterate" takes a delegate that returns something. But
that would be nice, to create, what look like, statements that return a
values.
--
/Jacob Carlborg