Why Ruby?

Jacob Carlborg doob at me.com
Sat Dec 18 10:09:24 PST 2010


On 2010-12-16 23:40, Nick Sabalausky wrote:
> "Andrei Alexandrescu"<SeeWebsiteForEmail at erdani.org>  wrote in message
> news:iedqos$787$1 at digitalmars.com...
>> On 12/16/10 1:30 PM, Jacob Carlborg wrote:
>>>
>>> The point here isn't that we want "a" and "b" to be replaced with "_"
>>> the point is that we want to get rid of the string and have a shorter
>>> and less verbose syntax for delegate literals.
>>
>> I understand. Using strings is witnessing the fact that we couldn't find a
>> shorter syntax that didn't have problems. That being said, it's very
>> possible there are some great ones, we just couldn't find them.
>>
>
> Any problem with the other Scala/C#-style one?:
>
> (x, y) =>   x * y
>
> // Lowered to:
>
> (x, y) { return x * y; }
>
> (Maybe that was rejected before due the the weird float operators that are
> now being ditched?)
>
> It wouldn't be used for delegates that involve actual statements (it would
> be expression-only), but that fits with the whole point of a lambda
> expression.
>
> Also, unlike the strings it doesn't suffer the problem of being evaluated in
> the wrong scope. For instance I think it's perfctly sensible to want a short
> lambda to be able to do something like this (pardon me if I have the syntax
> for map() wrong):
>
> int foo(int x) { ... }
> collection.map!"foo(a) + 3"();
> // Or if you want proper syntax highlighting:
> collection.map!q{ foo(a) + 3 }();
>
> I think that totally fits the charter of short lambdas, but the strings just
> can't do it (at least not without turning map() into something that needs to
> be mixed in). The lowered Scala/C#-style would be able to though:
>
> int foo(int x) { ... }
> collection.map!((a) =>  foo(a) + 3)();
> // Lowered to the messier:
> collection.map!((a) { return foo(a) + 3; })();

As Nick writes here the Scala/C#-style syntax is one suggestion. There 
are also several other syntaxes available, one just have to look at 
other languages to get ideas. Here's a list of the syntax used by a 
couple of different language, some languages are list more than once 
because they support more than one syntax. I've listed the languages in 
order from, what I think, the least verbose to the most verbose 
lambda/delegate syntax (the number in front of the languages is the 
level of verbose, if two languages are at the same level I think they 
are equally verbose).

1 D: foo(writeln(3)); // lazy argument
1 Scala: foo(_ * _)
2 C#: foo(x => x * x);
3 Scala: foo((x) => x * x)
4 Python: foo(lambda x: x * x)
5 Ruby: foo { |bar| x * x }
5 Ruby: foo do |x| x * x end
6 D: foo((int x) { return x * x; });
7 C++1x: foo([](int x){ return x * x; });
7 Apple's (Objective)-C(++) block extension: foo(^(int x){ return x * x; });
8 JavaScript: foo(function(x){ return x * x })
9 PHP: foo(function ($x) use($fooBar) { return $x * $x; }); // "use" is 
used for explicitly telling what variables should be available when the 
scope is gone.

Note that I have not listed any functional languages here because I've 
never used one.

I would like a syntax that is a combination of D's lazy argument syntax 
and C#'s lambda syntax. Basically like this:

If the lambda doesn't take have any parameters then you can just put the 
expression between then the parentheses in the function call:

foo(writeln(3));

If the lambda have one parameter then the following syntax is used:

foo(x => x * x);

If the lambda takes more then one parameter then you have to use 
parentheses around the lambda parameters like this:

foo((x, y) => x * y);

Actually if it would be possible to skip the parentheses when the lambda 
take more than one argument I would be more happy with that:

foo(x, y => x * y);

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list