Why Ruby?

Jacob Carlborg doob at me.com
Mon Dec 13 11:20:30 PST 2010


On 2010-12-13 20:04, Nick Sabalausky wrote:
> "Jacob Carlborg"<doob at me.com>  wrote in message
> news:ie5n2o$2v7s$2 at 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.

That's probably why one has to mess with the result of the delegate in 
opApply and it's also probably why opApply is unnecessary complicated.

But if I want the other behavior, just return from the delegate, is it 
common enough to support both behaviors?

BTW have a look at the following code:

struct Foo
{
     string array = "0123456789";

     int opApply(int delegate(ref char) dg)
     {
         int result = 0;

         for (int i = 0; i < array.length; i++)
         {
             result = dg(array[i]);
             //if (result)
                 //break;
         }

         return result;
     }
}

void bar ()
{
     Foo foo;

     foreach (c ; foo)
     {
         if (c == '3')
             return;

         writeln(c);
     }
}

void main ()
{
     bar();
}

With the "break" commented out the foreach will just continue even with 
the return.

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list