February 06, 2009
"Christopher Wright" <dhasenan@gmail.com> wrote in message news:gmfsqa$311e$1@digitalmars.com...
> Kagamin wrote:
>> 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.
>
> C# delegates in C# 2.0 are annoying. I try not to use them. The reason:
> D:
> void foo(void delegate(int) dg);
>
> C#:
> delegate void SomeName(int i);
> void foo(SomeName dg);
>
> Does C# 3 fix this? I've seen the new syntax for defining delegates, but not for using them.

C# provided my first introduction to delegates (not counting function-pointers in C), and that oddity actually made it harder for me to really wrap my head around them. Once I did though, I came around to D and thought "Wow! That's so simple!", and it actually helped me understand C#'s delegates better.

My only issue with D's delegate-declaration syntax is the semi-messy ordering of "return type, delegate keyword, paramaters, name". Something closer to following would seem much more intuitive to me:

void foo(delegate void(int) dg);
//or
void foo(void dg(int));
//or
void foo(delegate(void <- int) dg);
//etc...

Although, I realize the current way is done to be consistent with function definitions. But, as I mentioned in another branch of the thread, I wouldn't mind function definitions like this:

func foo(int <- int x) {return x+1;}
//or
func foo {(int <- int x) return x+1;}
//or
func foo {int <- int x :: return x+1;}


February 06, 2009
Christopher Wright wrote:
> C#:
> delegate void SomeName(int i);
> void foo(SomeName dg);

Ugh, don't remind me!
February 09, 2009
bearophile Wrote:
> Now, back to the topic: putting arguments into a single () or {} instead of a (){ return ;} (or with the => of C#) helps the eye see a single visual object isntead of two, this helps the human parsing of the code, improving visual chunking and reducing noise.

I also believe that, for readability reasons, lambdas should have some distinct token(s) in the beginning. C++ starts lambdas with brackets, []; C# has the distinct =>. I like the Haskell syntax that uses a backslash, which looks very much like lambda. Here's an example of such syntax:

auto r = find!( \(a) { return a.Weight > 100; })(range);

It goes without saying that any decent D editor would display the backslash as a Greek lambda.

February 09, 2009
Denis Koroskin Wrote:

> Could be used as follows:
> 
> foo( (i) { ++i; } );

Holy shi-
Now feel some real power, Luke. :)

foo( i => ++i );

>     foo((i){ ++i; }); // error
>     foo((i){ ++i; return;}); // unambiguous
>     foo((i){ return ++i;}); // unambiguous
February 09, 2009
On Mon, 09 Feb 2009 13:24:46 +0300, Kagamin <spam@here.lot> wrote:

> Denis Koroskin Wrote:
>
>> Could be used as follows:
>>
>> foo( (i) { ++i; } );
>
> Holy shi-
> Now feel some real power, Luke. :)
>
> foo( i => ++i );
>
>>     foo((i){ ++i; }); // error
>>     foo((i){ ++i; return;}); // unambiguous
>>     foo((i){ return ++i;}); // unambiguous

That was just an example. Those short lambdas are often used as predicates. Compare:

findAll(array, (i) { i > 3; });
findAll(array, (int i) { return i > 3; });

February 09, 2009
Denis Koroskin Wrote:

> That was just an example. Those short lambdas are often used as predicates. Compare:
> 
> findAll(array, (i) { i > 3; });
> findAll(array, (int i) { return i > 3; });
> 
well... you pwnd me :)
February 09, 2009
On Mon, Feb 9, 2009 at 3:19 AM, Bartosz Milewski <bartosz@relisoft.com> wrote:
> bearophile Wrote:
>> Now, back to the topic: putting arguments into a single () or {} instead of a (){ return ;} (or with the => of C#) helps the eye see a single visual object isntead of two, this helps the human parsing of the code, improving visual chunking and reducing noise.
>
> I also believe that, for readability reasons, lambdas should have some distinct token(s) in the beginning. C++ starts lambdas with brackets, []; C# has the distinct =>. I like the Haskell syntax that uses a backslash, which looks very much like lambda. Here's an example of such syntax:
>
> auto r = find!( \(a) { return a.Weight > 100; })(range);

Far too noisy.

auto r = find!(\a -> a.Weight > 100)(range);

Of course I _may_ be a bit biased in this regard, considering this is the syntax MiniD uses ;)

And of course, for multi-statement lambdas:

something(\a, b
{
    stmt1;
    stmt2;
});
February 09, 2009
Jarrett Billingsley:
> auto r = find!(\a -> a.Weight > 100)(range);
> [...]
> 
> something(\a, b
> {
>     stmt1;
>     stmt2;
> });

This looks better to me (but I don't know if this is the best syntax, it's just an idea):

// syntax for lambda that contains a single expression, implicit return (this is the most common case):
auto r = find!(a => a.Weight > 100)(range);

// syntax for lambda that contains one or more statements, no return, side effects only: something({ a, b :: stmt1; stmt2; });

// syntax for lambda that contains one or more statements, with side effects and return:
something({ a, b :: stmt1; return foo(); });

Bye,
bearophile
February 09, 2009
> // syntax for lambda that contains a single expression, implicit return (this is the most common case):
> auto r = find!(a => a.Weight > 100)(range);

I really like this one, but I'd prefer something like
> auto r = find(range, {a -> a.Weight > 100});

Note the -> instead of the =>, to avoid any ambiguities with the comparison operator.
February 09, 2009
grauzone Wrote:
> I really like this one, but I'd prefer something like
>  > auto r = find(range, {a -> a.Weight > 100});
> 
> Note the -> instead of the =>, to avoid any ambiguities with the comparison operator.

Let's play more; then what do you think about (all the following are legal):

auto r1 = range.find({ x -> x.weight > 100 });
auto r2 = range.find({ x :: return x.weight > 100; });
auto r3 = range.find({ x :: stmt1(x); stmt2; });
auto r4 = range.find({ x, y :: stmt1; return foo(y); });

I like those enough, they seem balanced, uniform, not too much error-prone, they have only one visual chunk, short enough and easy to write :-)

Note that this syntax:
auto r1 = range.find({ x -> x.weight > 100 });
using my dlibs is equivalent to the following:
auto r1 = range.find((ArrayType1!(typeof(range)) x) { return x.weight > 100; });

Bye,
bearophile