opApply/opApplyReverse return value types
Bill Baxter
dnewsgroup at billbaxter.com
Wed Oct 18 18:56:52 PDT 2006
BCS wrote:
> Jarrett Billingsley wrote:
>>
>> This works fine. I am returning -49 from opApply and it works fine.
>> I can return 0 from opApply and it works fine. I honestly have no
>> idea what the return from opApply is for.
>>
>
> I would assume that the generated delegate different return value for
> each goto and the return;
>
> void main(char argv[][])
> {
> int i = argv.length;
> foreach(a; new ForeachClass)
> {
> switch(i)
> {
> case 0: goto a;
> case 1: goto b;
> case 2: goto c;
> case 3: goto d;
> default: i/=4;
>
> case 76: return;
> }
> }
>
> a: writef("hi\n"); return;
> b: writef("Wee\n"); return;
> c: writef("Zzzz\n"); return;
> d: writef("Hrumph\n"); return;
> }
Damn, is that the only reason? Goto from inside a foreach must
constitute less than 1% of all use cases. It just doesn't seem right to
expose the user to that kind of implementation detail in a core language
construct. And probably 99% of those goto usages have a simple
workaround in the form of
bool done = false;
foreach(a; new ForeachClass)
{
switch(i)
{
...
default:
done = true;
//goto FINISH; not from a block!
case 76: return;
}
}
if (done) goto FINISH;
And there's probably even something cleaner using exceptions or scope
statements.
I wonder, can you goto out of an inner function? If not, why should you
be able to goto out of a foreach block?
Everyone raves about ruby blocks. Do they have gotos?
I'm guessing no. It seems D is /this/ close to being able to do
everything that Ruby blocks can do.
The main difference between ruby blocks and D's foreach seems to be that
in ruby, opApply effectively IS the foreach. So in pseudo ruby:
foreach(int i, &list.opApply)
/block/
Is something like
list.opApply()(int i)
/block/
That makes a lot of sense. Get rid of the foreach keyword. In truth
'foreach' knows nothing about 'foreach-ing'. All it knows is how to
call a delegate that knows how to foreach something. But that delegate
has no obligation to 'foreach'. It can just as easily return one random
item and stop. So the terminology in D is *backwards*. 'foreach' is
really something that knows how to apply a block-enclosing loop
construct to a block. 'opApply' is really a method that knows how to go
through the elements one-by-one. 'apply' should really be the D
keyword. 'foreach' should be the method name:
apply(int i, &list.foreach)
/block/
Wow. This makes so much sense to me now. That's why it seems so odd to
have both foreach and foreach_reverse to me. Because neither one really
knows anything about iterating in the first place(*). It's the methods
that have that knowledge. Everyone who doesn't know how ruby blocks
work should really go take 30 minutes and read up on it and compare with
how D does it. I found this link useful:
http://excastle.com/blog/archive/2005/05/18/1019.aspx
(*) Except for this pesky business about the special cases for arrays.
And honestly, to me, I don't think the overhead is that serious an
issue. It's ok to say you pay a little penalty for using foreach on an
array. If you want the fastest speed, use the for loop. But even with
foreach, you're still going to have performance 10x better than the best
foreach ruby or python can come up with.
--bb
More information about the Digitalmars-d-learn
mailing list