October 10, 2020
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven Schveighoffer wrote:
> I think if D is going to go this route, it needs to at least get rid of the ambiguity of => {return expr;}, which is currently "return a delegate/function that returns expr".

IMO this is a good idea regardless. I've fallen into the `=> { ... }` pit myself multiple times when refactoring from short to long delegate syntax, and I'm sure I'm not the only one.
October 10, 2020
On 10/10/20 7:25 AM, Patrick Schluter wrote:

> This is not adding a new feature, it's removing a restriction. The
> lambdas (i.e. unnamed functions) have 2 possible syntaxes. Named
> functions have only 1. This is inconsistent.

That.

Ali

October 10, 2020
On Saturday, 10 October 2020 at 23:22:30 UTC, Paul Backus wrote:
> IMO this is a good idea regardless.

Yeah, I've said before we should deprecate the whole {} thing and tell people to use () {} instead in all cases.

But minimally the => {} pattern specifically should be recognized and prohibited. The lexer itself could complain about the character sequence itself.
October 10, 2020
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven Schveighoffer wrote:
> 1. (v) => v.foo;
> 2. auto x(v) => v.foo;

The latter is almost guaranteed to issue a compile time error anyway but it should be simple enough to make it an error to have any anonymous parameter in this short syntax for declarations.

Maybe I can code it into the patch, it shouldn't be too complicated.
October 11, 2020
On Saturday, 10 October 2020 at 20:43:55 UTC, Steven Schveighoffer wrote:
> 1. is short for:
> (T)(T v) {
>   return v.foo;
> }

This technically isn't true... the lambda expression actually does context-dependent magic that this template can't represent either.

Like that is *part* of its implementation detail, but there's more to it.

So since it is indeed impossible to duplicate its context-dependent magic, I made it a parse error:

https://github.com/dlang/dmd/pull/11833/commits/acd15ce776af9bab336c14df20d77fbdc708e368

should be a happy enough compromise.
October 11, 2020
On 11.10.20 15:50, Adam D. Ruppe wrote:
> On Saturday, 10 October 2020 at 20:43:55 UTC, Steven Schveighoffer wrote:
>> 1. is short for:
>> (T)(T v) {
>>   return v.foo;
>> }
> 
> This technically isn't true... the lambda expression actually does context-dependent magic that this template can't represent either.
> 
> Like that is *part* of its implementation detail, but there's more to it.
> 
> So since it is indeed impossible to duplicate its context-dependent magic, I made it a parse error:
> 
> https://github.com/dlang/dmd/pull/11833/commits/acd15ce776af9bab336c14df20d77fbdc708e368 
> 
> 
> should be a happy enough compromise.

Just... why? Why add incidental complexity like this all? It's not like this has anything to do with the syntax of the lambda body. The original reasoning did not make any sense and this restriction is unnecessary.
October 11, 2020
On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote:
> Why add incidental complexity like this all?

That's why I kept the two commits separate. I'm not in love with it either but if it is what people want, it was simple enough to implement too. Or just skip that commit.
October 11, 2020
On 11.10.20 17:43, Adam D. Ruppe wrote:
> On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote:
>> Why add incidental complexity like this all?
> 
> That's why I kept the two commits separate. I'm not in love with it either but if it is what people want,

My point was that nobody should want that.

alias bar0=(v)=>v;
void foo0(v)=>v; // why special-case this,

alias bar1=(v){ return v; }
void foo1(v){ return v; } // but not this?

void baz0(int){ return 2; } // why is this fine,
void baz1(int)=>2;          // but this is not?

alias baz2=(int)=>2;        // and this is allowed!

The complaint is _orthogonal_ to what's being discussed.
This would add another special case just for the sake of making the language specification a bit longer.

(args)=>e is a shorthand for (args){ return e; } and this is a simple, consistent rule. What happens later in semantic is not the business of the parser.

> it was simple enough to implement too. Or just skip that commit.

+1.
October 11, 2020
On 10/11/20 12:04 PM, Timon Gehr wrote:
> On 11.10.20 17:43, Adam D. Ruppe wrote:
>> On Sunday, 11 October 2020 at 15:38:26 UTC, Timon Gehr wrote:
>>> Why add incidental complexity like this all?
>>
>> That's why I kept the two commits separate. I'm not in love with it either but if it is what people want,
> 
> My point was that nobody should want that.
> 
> alias bar0=(v)=>v;

In here, v is a parameter name.

> void foo0(v)=>v; // why special-case this,

here, v is a type, and this is not a valid function (functions cannot return types). We are not talking about invalid functions, but valid ones.

> 
> alias bar1=(v){ return v; }
> void foo1(v){ return v; } // but not this?

For a function declaration, if you want a templated value, you have to declare the template parameter. There is no short-hand syntax, like for lambdas.

> void baz0(int){ return 2; } // why is this fine,
> void baz1(int)=>2;          // but this is not?
> 
> alias baz2=(int)=>2;        // and this is allowed!

Lol, that last one, it only "works" because it's a keyword.

try this instead:

alias Int = int;

alias baz3= (Int) => 2;

baz3("hello"); // compiles, it's a function with a templated parameter named Int.
baz2("hello"); // error

Why make it not work? Because we have an opportunity to alleviate the confusion when introducing a new feature. We can relax it later if it makes sense to. But we can't impose a rule later that breaks code. Right now, no compiling code will be broken by this restriction.

> The complaint is _orthogonal_ to what's being discussed.
> This would add another special case just for the sake of making the language specification a bit longer.

To prevent confusion and inconsistency.

these two are equivalent "function-like" things:

alias x= (T t) => expr;
auto x(T t) { return expr;}

These two are not:

alias x = (t) => expr; // t is a parameter
auto x(t) => expr; // t is a type

> (args)=>e is a shorthand for (args){ return e; } and this is a simple, consistent rule. What happens later in semantic is not the business of the parser.

I don't think it needs to be a parser error.

-Steve
October 11, 2020
On 11.10.20 20:48, Steven Schveighoffer wrote:
> 
>> The complaint is _orthogonal_ to what's being discussed.
>> This would add another special case just for the sake of making the language specification a bit longer.
> 
> To prevent confusion and inconsistency.
> ...

This specifically adds more inconsistency. It does nothing useful on top of that, as our examples have demonstrated.

> these two are equivalent "function-like" things:
> 
> alias x= (T t) => expr;
> auto x(T t) { return expr;}
> 

alias x=(T t){ return expr; }
auto x(T t){ return expr; }

> These two are not:
> 
> alias x = (t) => expr; // t is a parameter
> auto x(t) => expr; // t is a type
> ...

alias x=(t){ return expr; }
auto x(t){ return expr; }

Not sure what you are trying to achieve by varying the syntax this way. `=>` or not `=>` has nothing to do with function literal semantics.

>> (args)=>e is a shorthand for (args){ return e; } and this is a simple, consistent rule. What happens later in semantic is not the business of the parser.
> 
> I don't think it needs to be a parser error.

The rewrite is performed in the parser.