Anonymous function syntax

Martin Nowak dawg at dawgfoto.de
Sat Sep 24 11:40:27 PDT 2011


On Sat, 24 Sep 2011 06:42:52 +0200, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 9/23/11 8:03 PM, Martin Nowak wrote:
>> On Thu, 22 Sep 2011 22:54:55 +0200, Andrei Alexandrescu
>> <SeeWebsiteForEmail at erdani.org> wrote:
>> 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.
>
> Well the C++2011 lambda syntax is quite foreign for C++ users, too.
>
>> 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
>
> I don't understand the point being made here.
>
>> 2. D is not a functional language, using the implies arrow in 'a =>
>> write(1, a.ptr, a.length)' creates a horribly association.
>
> Hackeyed as that sounds, D is a multi-paradigm language and includes a  
> lot of functional artifacts.
>
>> 3. I don't see any of the proposed rewrites is working for nullary
>> delegates.
>> '=> foo()' ???
>> Or '_ => foo()' => 'Error can't deduce parameter'.
>
> The comma-separated list may be empty.
>
>> 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.
>
> Not sure I understand this point either, sorry.
>

=> looks like an infix operator. It harder to distinguish in a parameter  
list.
The trailing right curly OTOH always ends a function.
It makes it visually distinct and is highlighted/matchable in an ide.
It prevents interaction of operators with the inner expression.

sort!((a, b) => a <= b)(input)
vs.
sort!((a, b) { a <= b })(input)

static assert ((a, b) => a < b != (a, b) => a > b)
vs.
static assert ((a, b) {a < b} != (a, b) {a > b})

Another minor issue:
a =>
   a + 3
Offers worse indentation for long expressions than
(a) {
   a + 3
}


>> 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
>
> We've been discussing the issues of this form.
>
>
> Andrei

I've only found one argument being made for this.

> 2. What if the lambda wants to actually evaluate the expression but  
> return void?
>  3. How is the semicolon relevant? (If its presence is used as a  
> disambiguator for (2), it's poor design to predicate a large semantic  
> difference on such a distinction.)

It will error when you want to use the return value of the delegate.
It will error when the expression has no side-effect.
It allows to easily create a void return delegate.
We already have implicit return for our second lambda syntax q{a+b}.

Having both (a, b) { foo(a, b); } and (a, b) => foo(a, b) for such similar  
constructs is no good design either.


C#, Scala and apparently Java8 all allow curly embraced statement blocks  
after the fat arrow.
Scala has an implicit return for this '() => { count += 1; count }'.
Will we allow statements () => { return 5; }?


We won't remove the existing function literal syntax due to code breakage.
We won't remove the string predicates because they are still shorter.
I am worried about having three subtly different language constructs for  
the same concept.

     (a, b) { return a < b; } |      q{a < b}     | (a, b) => a < b
        | old delegate syntax | string predicates | fat arrow delegates
        |--------------------------------------------------------------
scope  |    declaration      |   instantiation   |   declaration
return |    explicit         |   implicit        |   implicit
body   |    statements       |   expression      |   expression
types  |    optional         |   no              |   optional

martin


More information about the Digitalmars-d mailing list