Anonymous function syntax

Martin Nowak dawg at dawgfoto.de
Fri Sep 23 18:03:29 PDT 2011


On Thu, 22 Sep 2011 22:54:55 +0200, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 9/21/11 5:17 PM, Walter Bright wrote:
>> I've collected a few from various languages for comparison:
> [snip]
>
> I think we should do the following:
>
> 1. Introduce a new token "=>"
>
> 2. Add this rewrite to the grammar:
>
> symbol => expression
>
> translates to
>
> (symbol) { return expression; }
>
> 3. Add this rewrite to the grammar:
>
> symbol1 symbol2 => expression
>
> translates to
>
> (symbol1 symbol2) { return expression; }
>
> 4. Add this rewrite to the grammar:
>
> (comma_separated_parms) => expression
>
> translates to
>
> (comma_separated_parms) => expression
>
> Each item in comma_separated_parms may be 1 or 2 symbols separated by  
> whitespace. Example:
>
> (int a, b) => a + b
>
> is valid and translates to (int a, b) { return a + b; }
>
> 5. The expression cannot contain commas at top level; an unparenthesized  
> comma is considered to finish expression, just like in a function call's  
> argument list. For example:
>
> fun(int a => a + 1, a + 2)
>
> is interpreted as
>
> fun((int a => a + 1), (a + 2))
>
> To use comma inside expression, add parens around it.
>
> 5. Remove bugs and limitations. A function literal may specify none,  
> all, or some parameter types, and the compiler correctly figures out the  
> appropriate template and non-template parameters. The literal  
> subsequently converts to function pointer or delegate whenever there's a  
> match of parameter and result types.
>
>
>
> Andrei

I want to add some points against introducing this particular syntax.

1. Foremost using '=>' is unfamiliar. Comming from C++ or Java you really  
have to learn reading it.
    If you weighted the lambda syntaxes with the tiobe factor, arrows would  
be a minority.

How often have you stopped reading about a language because the code  
examples were unreadable?
Besides my liking for haskell, I don't want to see anything close to this  
on the D site.

mergesortBy less [] = []
mergesortBy less xs = head $ until (null.tail) pairs [[x] | x <- xs]
   where
     pairs (x:y:t) = merge x y : pairs t
     pairs xs      = xs
     merge (x:xs) (y:ys) | less y x  = y : merge (x:xs) ys
                         | otherwise = x : merge  xs (y:ys)
     merge  xs     ys                = xs ++ ys

2. D is not a functional language, using the implies arrow in 'a =>  
write(1, a.ptr, a.length)' creates a horribly association.

3. I don't see any of the proposed rewrites is working for nullary  
delegates.
    '=> foo()' ???
    Or '_ => foo()' => 'Error can't deduce parameter'.

4. The expression is badly delimited.
    The first rewrite symbol => expression
    is actually symbol => expression\{CommaExpression, CatExpression}.

    E.g.:
      dgs ~= (int a) => (a + 5) ~ (int a) => (a ^^ 2);
      foo(a, b => (log(b), b), c)
    And that with a pending tuple syntax reclaming even more parens, comma  
overloads.

So D is a curly bracket language.
http://en.wikipedia.org/wiki/List_of_programming_languages_by_category#Curly-bracket_languages
What is wrong the, I think earlier proposed, very simple solution.

http://www.digitalmars.com/d/2.0/expression.html#FunctionLiteral

FunctionLiteral:
     function Typeopt ParameterAttributes opt FunctionLiteralBody
     delegate Typeopt ParameterAttributes opt FunctionLiteralBody
     ParameterAttributes FunctionLiteralBody
     FunctionLiteralBody

ParameterAttributes:
     Parameters
     Parameters FunctionAttributes

FunctionLiteralBody:
     FunctionBody
     '{' Expression '}'

(a, b) {a+b}         // takes the same amount of characters
(a, b) {return a+b;} // return is no expression, be explicit
     () {call()}      // nullary

dgs ~= (int a){a + 5} ~ (int a){a ^^ 2};
foo(a, (b){log(b), b}, c)

You still can use the old variant without totally diverging in syntax.

  - It is brief
  - It uses very little syntax changes => less unknown traps

martin

P.S.:
I'm very undecided whether this should apply to functions too.
size_t foo() { 6 }

P.P.S.:
D already seems to have the briefest delegates.
http://en.wikipedia.org/wiki/Anonymous_function#Examples

P.P.P.S.:
One can use a full function body for delegates including contracts.
auto dg = delegate uint(int a) in{ assert(a >= 3); } body { return a - 3;  
};


More information about the Digitalmars-d mailing list