Why Ruby?

Jacob Carlborg doob at me.com
Mon Dec 13 10:00:16 PST 2010


On 2010-12-12 19:27, Nick Sabalausky wrote:
> "Jacob Carlborg"<doob at me.com>  wrote in message
> news:ie2g72$1sf3$1 at digitalmars.com...
>> On 2010-12-11 18:21, Andrei Alexandrescu wrote:
>>> On 12/11/10 11:05 AM, so wrote:
>>>> Not to hijack this one but on the other thread i asked why this is
>>>> needed.
>>>> I am not here asking for syntax or commanding phobos team to implement
>>>> something, I just want to know about technical limitations and license
>>>> issues, but got no answer to these.
>>>> Why? Either i am labeled here as a troll (maybe something worse since my
>>>> usage of English is not the best) or people here lack the vision (Oh
>>>> vision here actually bad usage since this bad practice have been here
>>>> forever, lack of eyesight would be the better definition)
>>>> One another thing might be that the community finds this issue is not an
>>>> important, (which makes me ask myself what you guys actually
>>>> developing).
>>>
>>> I don't think you're near the danger of being labeled as a troll. Would
>>> be great to focus the discussion a bit.
>>>
>>> For example, let's take a look at the code example given in the talk's
>>> first part that shows the beauty of Ruby. What does it look like in D?
>>> What can we do to make it look and behave better?
>>>
>>>
>>> Andrei
>>
>> If we take a look at the very first code example from the talk it looks
>> like this:
>>
>> account.people.each do |person|
>>      puts person.name
>> end
>>
>> You could translate this in two ways when translating into D.
>> First way:
>>
>> foreach (person ; account.people)
>>      writeln(person.name);
>>
>> I guess this is the most natural translation into D. If we want to be
>> closer to the Ruby code which uses a block we can translate the code to
>> use a delegate like this:
>>
>> account.people.each((Person person) {
>>      writeln(person.name);
>> });
>>
>> In my opinion this looks really ugly, D has no way of passing a delegate
>> to a function that looks good. If D could allow to pass a delegate to a
>> function outside the parameter list, after the function call, and had
>> better type inference it could look like this:
>>
>> account.people.each(person) {
>>      writeln(person.name);
>> }
>>
>> The above code is very close to the original Ruby code the only
>> differences is that D uses {} and Ruby uses "do" and "end".
>>
>
> 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"?

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list