"Jacob Carlborg" <d...@me.com> wrote in message 
news:ie5n2o$2v7...@digitalmars.com...
> On 2010-12-12 19:27, Nick Sabalausky wrote:
>>
>> There's one important difference you missed. Granted, it's not applicable 
>> in
>> that particular example, but more generally, it's important:
>>
>> int foo()
>> {
>>      foreach (person ; account.people)
>>      {
>>          writeln(person.name);
>>          if(blah)
>>              return 7; // Returns from foo
>>      }
>> }
>>
>>
>> int bar()
>> {
>>      account.people.each((Person person) {
>>          writeln(person.name);
>>          if(blah)
>>              return 7; // Only tries to return from the delegate
>>      });
>> }
>>
>> In D, there is currently no way to convert "foo()" above to use a delgate
>> (at least not without odd contorsions). So if we were to make syntax 
>> sugar
>> for "bar()", it would get really confusing:
>>
>> int bar2()
>> {
>>      account.people.each(Person person)
>>      {
>>          writeln(person.name);
>>          if(blah)
>>              return 7; // Only returns from the delegate, not bar2!! 
>> WTF?!
>>      }
>> }
>>
>> There are similar issues with break, continue, and probably goto.
>>
>> In Ruby, the syntax sugar works out fine because you can make it work it
>> either way. You can create something that behaves like a delegate 
>> ("return"
>> only returns from the delegate), or you can create something that is 
>> treated
>> as part of the function it's declared within ("return" unwinds the stack 
>> and
>> returns from the function that created it). (Although Ruby leaves the 
>> choice
>> up the the caller. I'm not entirely convinced that's the right way to do
>> it.)
>>
>> D would need something similar for "passing a delegate" sugar to work out
>> sensibly. One idea is to say that if-and-only-if the "sugar" is used, 
>> it's
>> considered part of the original function that declared it rather than 
>> being
>> a true degelate. The function that takes the "sugared delegate" must 
>> declare
>> that it takes a "sugared delegate" instead of a normal one so that it can
>> make sure not to do this:
>>
>> doSomething();
>> callSugaredDelegateThatMightUnwindTheStackEvenWithoutThrowing();
>> doCleanup();
>
> Yes, absolutely correct, I totally forgot about this. D would need a way 
> to return from the delegate and a way to return from the context where the 
> delegate is called. Perhaps introduce a new keyword "yield"?
>

I've been reminded in another branch of this thread that foreach/opApply 
already handles this issue, so that approach could probably just be copied. 
Ie with:

foreach(item; somethingWithOpApply)
{
    if(item.isItBoyant())
        return item;
}

The body gets converted to a delegate which gets passed to opApply, but the 
"return" still works as expected. I would be interested to hear how exactly 
that works though, particularly when returning something other than void.


Reply via email to