Lambda syntax, etc
Denis Koroskin
2korden at gmail.com
Thu Feb 5 08:04:20 PST 2009
On Thu, 05 Feb 2009 17:25:38 +0300, Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> Denis Koroskin wrote:
>> On Thu, 05 Feb 2009 12:32:15 +0300, Kagamin <spam at here.lot> wrote:
>>
>>> bearophile Wrote:
>>>
>>>> C#2 has lambdas, and C#3 adds closures and more type inferencing, so
>>>> C#3+ supports the following syntaxes:
>>>> (int i) => { return i % 3 == 1; } // C#2
>>>> i => i % 3 == 1 // C#3
>>>> i => { return i % 3 == 1; } // C#3, with statements too
>>>> To define a delegate o delegate closure:
>>>> Func<int> foo = i => { return i % 3 == 1; };
>>>> Func<int> foo = i => i % 3 == 1;
>>>> Func<int> bar = () => 2;
>>>> But this isn't allowed:
>>>> Func<void> bar = () => 2;
>>>
>>> Yeah, C# lambdas are the killer feature. Slick, readable,
>>> C-compatible. Anders knows his job. Let's face it: delegate literals
>>> suck a little, mixins as delegates suck a lot, the former is too
>>> verbose, the latter just sucks.
>> I don't like C# lambda syntax (although it is not half as bad as C++
>> lambda syntax).
>> I believe D delegate syntax is superior due to its natural and
>> unambiguous syntax.
>> But yes, it could be made shorter by improving type deduction:
>> int delegate(int) inc = (i) { i + 1; }
>> Which would be the same as
>> int delegate(int) inc = (int i) { return i + 1; }
>
> What if you wanted to just execute one expression and return void? This
> is relevant when e.g. large objects are involved that shouldn't be
> copied unwittingly.
>
No problem:
void delegate(int) inc = (i) { i + 1; };
which would be transformed into
void delegate(int) inc = (int i) { i + 1; };
or
void delegate(int) inc = (int i) { return i + 1; };
Both are valid D code according to specs[1].
The second one doesn't compile as of now, but this is a DMD bug, I assume.
>> where i's type is deduced from inc's type and the only expression (i +
>> 1) made a return value:
>> auto x = inc(5); // yields 6
>> Here is an another example:
>> void foo(void delegate(ref int i) inc);
>> Could be used as follows:
>> foo( (i) { ++i; } );
>> as opposed to
>> foo( (ref int i) { ++i; } );
>
> Aha! So here you are using a void-returning function. Now what if there
> was another overload of foo in place:
>
> void foo(int delegate(ref int i) inc);
>
> Which foo is to be called? The one that infers a return type of int or
> the one that assumes the code just returns void?
>
1) Compiler can flag an ambiguity error at compile time so that user resolve it:
foo((i){ ++i; }); // error
foo((i){ ++i; return;}); // unambiguous
foo((i){ return ++i;}); // unambiguous
2) (The one I prefer) Make (i) { ++i; } return int. The following could be used to force void return type:
foo((i){ ++i;; }); // note the double semicolon.
It returns void for two reasons:
a) second ; evaluates to void
b) it is not a single-statement delegate anymore.
Implicit return should only be allowed for single statement delegates that are very frequently used (mostly as a predicate) and almost never return void.
I doubt it will lead to errors. The very example is rather artificial.
>> I can put this enhancement request into bugzilla if anyone likes it.
>
> It would be great to add the parameter type deduction stuff; that is
> already talked about and doesn't seem to have many issues. It does have
> one, which I'm sure people here will see rather quickly.
>
>
> Andrei
---
[1]statement.html:
ReturnStatement:
return;
return Expression;
Expression is allowed even if the function specifies a void return type. The Expression will be evaluated, but nothing will be returned.
More information about the Digitalmars-d
mailing list