Re: Should aliasing a lambda expression be allowed?

2017-11-18 Thread Timon Gehr via Digitalmars-d

On 15.11.2017 15:07, Jonathan M Davis wrote:

In general, alias aliases symbols, whereas a lambda isn't a symbol. ...


There is essentially no merit to the symbol/no symbol distinction. It's 
just a DMD implementation detail resulting in weird inconsistencies 
between alias declarations and alias template parameters that are being 
fixed one by one.



...
alias foo = int;
alias foo = float;


Case in point. Neither int nor float are symbols.


Re: Should aliasing a lambda expression be allowed?

2017-11-18 Thread Timon Gehr via Digitalmars-d

On 15.11.2017 13:28, Steven Schveighoffer wrote:


However, it would be good to prevent the second alias which effectively 
does nothing.


No. It should just overload properly.


Re: Should aliasing a lambda expression be allowed?

2017-11-16 Thread Meta via Digitalmars-d

On Thursday, 16 November 2017 at 16:10:50 UTC, Meta wrote:

int function(int) f1 = (int n) => n;
int function(int) f2 = (char c) => c;


Should be int function(char)



Re: Should aliasing a lambda expression be allowed?

2017-11-16 Thread Meta via Digitalmars-d
On Thursday, 16 November 2017 at 13:05:51 UTC, Petar Kirov 
[ZombineDev] wrote:
On Wednesday, 15 November 2017 at 19:29:29 UTC, Steven 
Schveighoffer wrote:

On 11/15/17 11:59 AM, Andrea Fontana wrote:
On Wednesday, 15 November 2017 at 15:25:06 UTC, Steven 
Schveighoffer wrote:

alias foo = lambda1;
alias foo = lambda2;


What?


Yep. Would never have tried that in a million years before 
seeing this thread :) But it does work. Tested with dmd 
2.076.1 and 2.066. So it's been there a while.


-Steve


I guess you guys haven't been keeping up with language changes 
:P


https://dlang.org/changelog/2.070.0.html#alias-funclit

And yes, you can use 'alias' to capture overload sets.
See also:

https://github.com/dlang/dmd/pull/1660/files
https://github.com/dlang/dmd/pull/2125/files#diff-51d0a1ca6214e6a916212fcbf93d7e40
https://github.com/dlang/dmd/pull/2417/files
https://github.com/dlang/dmd/pull/4826/files
https://github.com/dlang/dmd/pull/5162/files
https://github.com/dlang/dmd/pull/5202

https://github.com/dlang/phobos/pull/5818/files


Yes, as far as I understand this is just the normal way that you 
add a symbol to an existing overload set, except now it also 
interacts with the functionality of using an alias to create a 
named function literal. Kind of interesting because I don't think 
it was possible to do this before, e.g.:


int function(int) f1 = (int n) => n;
int function(int) f2 = (char c) => c;

Would obviously be rejected by the compiler. However, using the 
alias syntax we can  create an overload set from function 
literals in addition to regular functions.


Re: Should aliasing a lambda expression be allowed?

2017-11-16 Thread Petar via Digitalmars-d
On Wednesday, 15 November 2017 at 19:29:29 UTC, Steven 
Schveighoffer wrote:

On 11/15/17 11:59 AM, Andrea Fontana wrote:
On Wednesday, 15 November 2017 at 15:25:06 UTC, Steven 
Schveighoffer wrote:

alias foo = lambda1;
alias foo = lambda2;


What?


Yep. Would never have tried that in a million years before 
seeing this thread :) But it does work. Tested with dmd 2.076.1 
and 2.066. So it's been there a while.


-Steve


I guess you guys haven't been keeping up with language changes :P

https://dlang.org/changelog/2.070.0.html#alias-funclit

And yes, you can use 'alias' to capture overload sets.
See also:

https://github.com/dlang/dmd/pull/1660/files
https://github.com/dlang/dmd/pull/2125/files#diff-51d0a1ca6214e6a916212fcbf93d7e40
https://github.com/dlang/dmd/pull/2417/files
https://github.com/dlang/dmd/pull/4826/files
https://github.com/dlang/dmd/pull/5162/files
https://github.com/dlang/dmd/pull/5202

https://github.com/dlang/phobos/pull/5818/files


Re: Should aliasing a lambda expression be allowed?

2017-11-15 Thread Steven Schveighoffer via Digitalmars-d

On 11/15/17 11:59 AM, Andrea Fontana wrote:

On Wednesday, 15 November 2017 at 15:25:06 UTC, Steven Schveighoffer wrote:

alias foo = lambda1;
alias foo = lambda2;


What?


Yep. Would never have tried that in a million years before seeing this 
thread :) But it does work. Tested with dmd 2.076.1 and 2.066. So it's 
been there a while.


-Steve


Re: Should aliasing a lambda expression be allowed?

2017-11-15 Thread Andrea Fontana via Digitalmars-d
On Wednesday, 15 November 2017 at 15:25:06 UTC, Steven 
Schveighoffer wrote:

alias foo = lambda1;
alias foo = lambda2;


What?


Re: Should aliasing a lambda expression be allowed?

2017-11-15 Thread Steven Schveighoffer via Digitalmars-d

On 11/15/17 9:07 AM, Jonathan M Davis wrote:

On Wednesday, November 15, 2017 07:28:02 Steven Schveighoffer via
Digitalmars-d wrote:

On 11/14/17 8:56 PM, Michael V. Franklin wrote:

On Tuesday, 14 November 2017 at 23:41:39 UTC, Steven Schveighoffer

wrote:

In fact, I'm surprised you can alias to an expression like that.
Usually you need a symbol. It's probably due to how this is lowered.


Boy did I "step in it" with my original post:  Started out with one
issue and ended up with 3.

I looked at what the compiler is doing, and it is generated a new symbol
(e.g. `__lambda4`).  I suspect this is not intended.

My question now is, should the compiler actually be treating the lambda
as an expression instead of a new symbol, thus disallowing it
altogether? (sigh! more breakage)?


I don't think we can prevent the aliasing in the first place, because if
this is possible, I guarantee people use it, and it looks quite handy
actually. Much less verbose than templates:

alias mul = (a, b) => a * b;

vs.

auto mul(A, B)(A a, B b) { return a * b; }


In general, alias aliases symbols, whereas a lambda isn't a symbol. They're
essentially the rvalue equivalent of functions. So, in that sense, it's
pretty weird that it works. However, we _do_ use it all the time with alias
template parameters. So, regardless of what would make sense for other
aliases, if we just made it so that alias in general didn't work with
lambdas, we'd be in big trouble. It wouldn't surprise me if the fact that
aliases like this works with lambdas is related to the fact that it works
with alias template parameters, but I don't know. It may simply be that
because of how the compiler generates lambdas, it ends up with a name for
them (even if you don't see it), and it just naturally came out that those
were aliasable.


However, it would be good to prevent the second alias which effectively
does nothing.


As far as I'm concerned, in principal, it's identical to declaring a
variable with the same name in the same scope, and I'm very surprised that
it
works. Interestingly, this code

alias foo = int;
alias foo = float;


alias statements and alias parameters have differences, so I don't know 
if there is any real relation here. For example, int cannot bind to a 
template alias.


Some really weird stuff is going on with aliasing and function overloads 
in general.


If we change them from anonymous lambdas to actual functions:

auto lambda1(char c) { return 1; }
auto lambda2(int i) { return 4; }

alias foo = lambda1;
alias foo = lambda2;

void main()
{
   assert(foo('a') == 1);
   assert(foo(1) == 4);
}

Hey look, it all works!

Even if lambda1 and lambda2 are turned into templates, it works.

I seriously did not expect this to work.

-Steve


Re: Should aliasing a lambda expression be allowed?

2017-11-15 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, November 15, 2017 07:28:02 Steven Schveighoffer via 
Digitalmars-d wrote:
> On 11/14/17 8:56 PM, Michael V. Franklin wrote:
> > On Tuesday, 14 November 2017 at 23:41:39 UTC, Steven Schveighoffer 
wrote:
> >> In fact, I'm surprised you can alias to an expression like that.
> >> Usually you need a symbol. It's probably due to how this is lowered.
> >
> > Boy did I "step in it" with my original post:  Started out with one
> > issue and ended up with 3.
> >
> > I looked at what the compiler is doing, and it is generated a new symbol
> > (e.g. `__lambda4`).  I suspect this is not intended.
> >
> > My question now is, should the compiler actually be treating the lambda
> > as an expression instead of a new symbol, thus disallowing it
> > altogether? (sigh! more breakage)?
>
> I don't think we can prevent the aliasing in the first place, because if
> this is possible, I guarantee people use it, and it looks quite handy
> actually. Much less verbose than templates:
>
> alias mul = (a, b) => a * b;
>
> vs.
>
> auto mul(A, B)(A a, B b) { return a * b; }

In general, alias aliases symbols, whereas a lambda isn't a symbol. They're
essentially the rvalue equivalent of functions. So, in that sense, it's
pretty weird that it works. However, we _do_ use it all the time with alias
template parameters. So, regardless of what would make sense for other
aliases, if we just made it so that alias in general didn't work with
lambdas, we'd be in big trouble. It wouldn't surprise me if the fact that
aliases like this works with lambdas is related to the fact that it works
with alias template parameters, but I don't know. It may simply be that
because of how the compiler generates lambdas, it ends up with a name for
them (even if you don't see it), and it just naturally came out that those
were aliasable.

> However, it would be good to prevent the second alias which effectively
> does nothing.

As far as I'm concerned, in principal, it's identical to declaring a
variable with the same name in the same scope, and I'm very surprised that 
it
works. Interestingly, this code

alias foo = int;
alias foo = float;

_does_ produce an error. So, it looks like it's a problem related to lambdas
specifically.

- Jonathan M Davis



Re: Should aliasing a lambda expression be allowed?

2017-11-15 Thread Steven Schveighoffer via Digitalmars-d

On 11/14/17 8:56 PM, Michael V. Franklin wrote:

On Tuesday, 14 November 2017 at 23:41:39 UTC, Steven Schveighoffer wrote:
In fact, I'm surprised you can alias to an expression like that. 
Usually you need a symbol. It's probably due to how this is lowered.


Boy did I "step in it" with my original post:  Started out with one 
issue and ended up with 3.


I looked at what the compiler is doing, and it is generated a new symbol 
(e.g. `__lambda4`).  I suspect this is not intended.


My question now is, should the compiler actually be treating the lambda 
as an expression instead of a new symbol, thus disallowing it 
altogether? (sigh! more breakage)?


I don't think we can prevent the aliasing in the first place, because if 
this is possible, I guarantee people use it, and it looks quite handy 
actually. Much less verbose than templates:


alias mul = (a, b) => a * b;

vs.

auto mul(A, B)(A a, B b) { return a * b; }

However, it would be good to prevent the second alias which effectively 
does nothing.


-Steve