Re: Should aliasing a lambda expression be allowed?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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