opApply/opApplyReverse return value types

BCS BCS at pathlink.com
Thu Oct 19 09:32:16 PDT 2006


Bill Baxter wrote:
> 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.

also labeled breaks and continues:

l1: foreach(i; obj1)
{
	l2: foreach(j; obj2)
	{
		if(j.foo) continue l1;
		if(j.bar) break l1;
		if(j.can) goto skip;
	}
	// something
	skip:
	// something else
}


OTOH the block is a delegate so it could stuff that value into a 
variable local to the outer scope and then return a "quit" value.

void foo()
{
	Obj obj1,  obj2;

	obj1.opApply((i){
		int returnAction;
		if(!obj1.opApply((j){
			if(j.foo)
			{
				returnAction = 1;
				return false;
			}
			if(j.bar) break l1;
			{
				returnAction = 2;
				return false;
			}
			if(j.can)
			{
				returnAction = 3;
				return false;
			}
		
		}))
		switch(returnAction)
		{
			case 1:
				return true;
			case 2:
				return false;
			case 3:
				goto skip;
		}
		// something
		skip:
		// something else
	});
}


more or less what you proposed

   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.
> 

Who cares about clean? The compiler's doing it, all that I want is fast 
code.

> I wonder, can you goto out of an inner function?  If not, why should you 
> be able to goto out of a foreach block?'

because it shouldn't act any different than an if block in that respect.



More information about the Digitalmars-d-learn mailing list