digitalmars.D - Better lambdas!!!!!!!!!!
- Prudence (12/12) Sep 10 2015 How bout this:
- Adam D. Ruppe (3/5) Sep 10 2015 You could also write `myfunc((i,z,f) => i*z*f);` right now. The
- =?UTF-8?Q?Ali_=c3=87ehreli?= (11/17) Sep 10 2015 Considering other features of the language, that's pretty much
- Prudence (21/44) Sep 11 2015 As I said, it could throw a warning or error. It, in some sense,
- Pierre Krafft (13/63) Sep 11 2015 You're making your code more brittle for a small gain. The
- Prudence (34/111) Sep 11 2015 What does this have to do with my proposal? Those issues exist
- Pierre Krafft (21/134) Sep 12 2015 myfunc({return "x:"~x~"y:"-y;});
- anonymous (5/8) Sep 10 2015 This makes the parameter names part of the API. The author of a
- Jonathan M Davis (7/15) Sep 10 2015 That's one of the main reasons that I hate the idea of named
- wobbles (3/19) Sep 10 2015 +1
- Timon Gehr (3/8) Sep 11 2015 Note that parameter names can already be determined by user code using
- Jonathan M Davis (9/22) Sep 11 2015 True, but as soon as you're doing much with reflection, all bets
- Jacob Carlborg (17/18) Sep 12 2015 In Ruby named arguments need to be explicitly requested when declaring a...
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (7/9) Sep 12 2015 Python has similar semantics. Very useful to force explicitness
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (3/10) Sep 10 2015 How about just having numbered parameters like this:
- Meta (11/13) Sep 10 2015 What about this situation?
- Meta (2/16) Sep 10 2015 Should be `return first > second ? $1 : $2`, but you get the idea.
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (3/5) Sep 10 2015 If there is a conflict you should use a regular lambda on the
- Meta (7/9) Sep 10 2015 You could, but then doesn't that defeat the point a bit? My
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (8/17) Sep 10 2015 Yes, it is usually it is a bad idea to have many ways to do
- Idan Arye (33/42) Sep 10 2015 Clojure solved this by disallowing nesting
- Jacob Carlborg (9/10) Sep 12 2015 No, I don't think it does. For example in Scala you can do like this:
- Adam D. Ruppe (7/9) Sep 10 2015 The string lambdas Phobos supports basically does this:
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (3/8) Sep 10 2015 Isn't that a string mixin? Or?
- Russel Winder via Digitalmars-d (14/23) Sep 11 2015 And until some bugs get fixed, you have to use string functions in some
- ZombineDev (2/15) Sep 11 2015 Can you elaborate? Are those bugs logged somewhere?
- Russel Winder via Digitalmars-d (13/30) Sep 11 2015 For example https://issues.dlang.org/show_bug.cgi?id=3D5710
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (3/4) Sep 11 2015 If C++ interop is still important, maybe it would be a good idea
- Jonathan M Davis (17/22) Sep 11 2015 How would that help with interop? Even if we supported passing a
- Ola Fosheim Grostad (4/10) Sep 11 2015 No, you have to generate c++ sourcecode. No need to build in the
How bout this: void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } } vs myfunc({ return i*z*f; }) // Names of parameters are inferred from signature. by specifying the parameter names in the signature, we don't have to specify them in the lamba creation. This doesn't replace the original way, just adds the ability to infer the names if they are not specified. Of course, this hides the names outside the lambda, but a warning could be issued(no different than if one does it explicitly.
Sep 10 2015
On Thursday, 10 September 2015 at 17:55:06 UTC, Prudence wrote:void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } }You could also write `myfunc((i,z,f) => i*z*f);` right now. The names are easy to do.
Sep 10 2015
On 09/10/2015 10:55 AM, Prudence wrote:How bout this: void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } } vs myfunc({ return i*z*f; }) // Names of parameters are inferred from signature.Considering other features of the language, that's pretty much impossible in D. What if there is another i in scope: int i; myfunc({ return i*z*f; }); Now, should it call another overload of myfunc that takes (int z, int f) because i is something else? Should the compiler analyze the body of the code and decide which symbols could be parameters? And then go through all overloads of myfunc? etc.? Ali
Sep 10 2015
On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli wrote:On 09/10/2015 10:55 AM, Prudence wrote:As I said, it could throw a warning or error. It, in some sense, is already a a problem with nested blocks that hide outside variables, is it not? The compiler doesn't need to scan anything. It knows the which parameters from the definition! -> void myfunc(double delegate(int i, int z, float f)) <- Compiler knows to use the names here as the default names in for the parameters when. when used: myfunc({ return i*z*f; }); <- Oh, there are the names, we know what they are because the signature is tells us. The compiler does the following: 1. Sees we have a block without any parameters defined. i.e., a lambda. 2. It looks up the signature of myfunc to find out what the names are 3. It sees that they are i z and f 4. Now it knows and it effectively rewrites the code as myfunc((i,z,f) { return i*z*f; }); Surely this is not difficult, 4 steps?How bout this: void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } } vs myfunc({ return i*z*f; }) // Names of parameters areinferred fromsignature.Considering other features of the language, that's pretty much impossible in D. What if there is another i in scope: int i; myfunc({ return i*z*f; }); Now, should it call another overload of myfunc that takes (int z, int f) because i is something else? Should the compiler analyze the body of the code and decide which symbols could be parameters? And then go through all overloads of myfunc? etc.? Ali
Sep 11 2015
On Saturday, 12 September 2015 at 01:03:54 UTC, Prudence wrote:On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli wrote:You're making your code more brittle for a small gain. The suggestion makes parameter usage order important and the compiler can't warn about my typos. Consider: myfunc({return "x:"~x~"y:"-y;}) getting changed to myfunc({return "y:"~y~"x:"~x;}); Or the typo in myfunc({return i*z+f*j;}); Lambdas are already very concise. This proposal doesn't give any benefits outside of very simple lambdas. Such lambdas are already so simple that they could use some standard functions instead (like sum, to!T, and bind).On 09/10/2015 10:55 AM, Prudence wrote:As I said, it could throw a warning or error. It, in some sense, is already a a problem with nested blocks that hide outside variables, is it not? The compiler doesn't need to scan anything. It knows the which parameters from the definition! -> void myfunc(double delegate(int i, int z, float f)) <- Compiler knows to use the names here as the default names in for the parameters when. when used: myfunc({ return i*z*f; }); <- Oh, there are the names, we know what they are because the signature is tells us. The compiler does the following: 1. Sees we have a block without any parameters defined. i.e., a lambda. 2. It looks up the signature of myfunc to find out what the names are 3. It sees that they are i z and f 4. Now it knows and it effectively rewrites the code as myfunc((i,z,f) { return i*z*f; }); Surely this is not difficult, 4 steps?How bout this: void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } } vs myfunc({ return i*z*f; }) // Names of parameters areinferred fromsignature.Considering other features of the language, that's pretty much impossible in D. What if there is another i in scope: int i; myfunc({ return i*z*f; }); Now, should it call another overload of myfunc that takes (int z, int f) because i is something else? Should the compiler analyze the body of the code and decide which symbols could be parameters? And then go through all overloads of myfunc? etc.? Ali
Sep 11 2015
On Saturday, 12 September 2015 at 02:13:11 UTC, Pierre Krafft wrote:On Saturday, 12 September 2015 at 01:03:54 UTC, Prudence wrote:What does this have to do with my proposal? Those issues exist regardless of the simplification. myfunc({return "x:"~x~"y:"-y;}) getting changed to myfunc({return "y:"~y~"x:"~x;}); huh? What do you mean the suggestion makes parameter usage order important? They are important, it has nothing to do with the suggestion? Are you saying that you want to reserve the right to do something like myfunc(string delegate(string x, string y)); and myfunc((y,x){ "y:"~y~"x:"~x; }) ? If so, or unless I'm missing something, that's bad no matter what. Changing the order and reversing the names is more than just confusing, it's hard to read and most people will gloss over that fact. Be consistent with your parameters and maybe you'll have less bugs? Or the typo in myfunc({return i*z+f*j;}); Again, what does this have to do with anything? A typo is a typo and is always a mistake. The above example has the same effect regardless if the parameters are explicit or deduced. myfunc((i,z,f) {return i*z+f*j;}); j is still a problem. If j is defined outside the lambda then regardless of specific or implicit parameter names, it will not cause any problems. In either case, the compiler can see that j is either referenced outside the scope or undefined. It has nothing to do with the parameters used. Of course maybe I'm missing something, but essentially are not almost all uses of lambda's simply copying the parameter signature of the delegate. It already infers types... you could say that leads to typo's too...On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli wrote:You're making your code more brittle for a small gain. The suggestion makes parameter usage order important and the compiler can't warn about my typos. Consider: myfunc({return "x:"~x~"y:"-y;}) getting changed to myfunc({return "y:"~y~"x:"~x;}); Or the typo in myfunc({return i*z+f*j;}); Lambdas are already very concise. This proposal doesn't give any benefits outside of very simple lambdas. Such lambdas are already so simple that they could use some standard functions instead (like sum, to!T, and bind).On 09/10/2015 10:55 AM, Prudence wrote:As I said, it could throw a warning or error. It, in some sense, is already a a problem with nested blocks that hide outside variables, is it not? The compiler doesn't need to scan anything. It knows the which parameters from the definition! -> void myfunc(double delegate(int i, int z, float f)) <- Compiler knows to use the names here as the default names in for the parameters when. when used: myfunc({ return i*z*f; }); <- Oh, there are the names, we know what they are because the signature is tells us. The compiler does the following: 1. Sees we have a block without any parameters defined. i.e., a lambda. 2. It looks up the signature of myfunc to find out what the names are 3. It sees that they are i z and f 4. Now it knows and it effectively rewrites the code as myfunc((i,z,f) { return i*z*f; }); Surely this is not difficult, 4 steps?How bout this: void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } } vs myfunc({ return i*z*f; }) // Names of parameters areinferred fromsignature.Considering other features of the language, that's pretty much impossible in D. What if there is another i in scope: int i; myfunc({ return i*z*f; }); Now, should it call another overload of myfunc that takes (int z, int f) because i is something else? Should the compiler analyze the body of the code and decide which symbols could be parameters? And then go through all overloads of myfunc? etc.? Ali
Sep 11 2015
On Saturday, 12 September 2015 at 03:32:51 UTC, Prudence wrote:On Saturday, 12 September 2015 at 02:13:11 UTC, Pierre Krafft wrote:myfunc({return "x:"~x~"y:"-y;}); is infered to mean myfunc((x,y){return "x:"~x~"y:"-y;}); while myfunc({return "y:"~y~"x:"~x;}); is infered to mean myfunc((y,x){return "y:"~y~"x:"~x;}); which is not what I expect since the lambda I want is myfunc((x,y){return "y:"~y~"x:"~x;}); This can lead to subtle bugs which are very hard to see. In the typo example there could be two overloaded functions differing only in that one takes a delegate having 3 parameters and one taking a delegate having 4 parameters. If we explicitly write the lambda parameters the typo will be found since j is undefined. But when parameters are inferred the compiler will see that {return i*z + f*j;} matches the function taking a lambda with 4 parameters. Inferred parameter types are on the brink of what I can allow. They can risk typos, but not as easily since you write the parameters twice (declaration and usage). They can also silently change if the function taking the delegate has the parameter type changed. I don't want to add more magic to that area.On Saturday, 12 September 2015 at 01:03:54 UTC, Prudence wrote:What does this have to do with my proposal? Those issues exist regardless of the simplification. myfunc({return "x:"~x~"y:"-y;}) getting changed to myfunc({return "y:"~y~"x:"~x;}); huh? What do you mean the suggestion makes parameter usage order important? They are important, it has nothing to do with the suggestion? Are you saying that you want to reserve the right to do something like myfunc(string delegate(string x, string y)); and myfunc((y,x){ "y:"~y~"x:"~x; }) ? If so, or unless I'm missing something, that's bad no matter what. Changing the order and reversing the names is more than just confusing, it's hard to read and most people will gloss over that fact. Be consistent with your parameters and maybe you'll have less bugs? Or the typo in myfunc({return i*z+f*j;}); Again, what does this have to do with anything? A typo is a typo and is always a mistake. The above example has the same effect regardless if the parameters are explicit or deduced. myfunc((i,z,f) {return i*z+f*j;}); j is still a problem. If j is defined outside the lambda then regardless of specific or implicit parameter names, it will not cause any problems. In either case, the compiler can see that j is either referenced outside the scope or undefined. It has nothing to do with the parameters used. Of course maybe I'm missing something, but essentially are not almost all uses of lambda's simply copying the parameter signature of the delegate. It already infers types... you could say that leads to typo's too...On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli wrote:You're making your code more brittle for a small gain. The suggestion makes parameter usage order important and the compiler can't warn about my typos. Consider: myfunc({return "x:"~x~"y:"-y;}) getting changed to myfunc({return "y:"~y~"x:"~x;}); Or the typo in myfunc({return i*z+f*j;}); Lambdas are already very concise. This proposal doesn't give any benefits outside of very simple lambdas. Such lambdas are already so simple that they could use some standard functions instead (like sum, to!T, and bind).On 09/10/2015 10:55 AM, Prudence wrote:As I said, it could throw a warning or error. It, in some sense, is already a a problem with nested blocks that hide outside variables, is it not? The compiler doesn't need to scan anything. It knows the which parameters from the definition! -> void myfunc(double delegate(int i, int z, float f)) <- Compiler knows to use the names here as the default names in for the parameters when. when used: myfunc({ return i*z*f; }); <- Oh, there are the names, we know what they are because the signature is tells us. The compiler does the following: 1. Sees we have a block without any parameters defined. i.e., a lambda. 2. It looks up the signature of myfunc to find out what the names are 3. It sees that they are i z and f 4. Now it knows and it effectively rewrites the code as myfunc((i,z,f) { return i*z*f; }); Surely this is not difficult, 4 steps?How bout this: void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } } vs myfunc({ return i*z*f; }) // Names of parameters areinferred fromsignature.Considering other features of the language, that's pretty much impossible in D. What if there is another i in scope: int i; myfunc({ return i*z*f; }); Now, should it call another overload of myfunc that takes (int z, int f) because i is something else? Should the compiler analyze the body of the code and decide which symbols could be parameters? And then go through all overloads of myfunc? etc.? Ali
Sep 12 2015
On Saturday, 12 September 2015 at 10:44:05 UTC, Pierre Krafft wrote:myfunc({return "x:"~x~"y:"-y;}); is infered to mean myfunc((x,y){return "x:"~x~"y:"-y;}); while myfunc({return "y:"~y~"x:"~x;}); is infered to mean myfunc((y,x){return "y:"~y~"x:"~x;}); which is not what I expect since the lambda I want is myfunc((x,y){return "y:"~y~"x:"~x;}); This can lead to subtle bugs which are very hard to see.I don't think this is what the OP was suggesting. As far as I understand, the suggestion was that the lambda's arguments would be inferred from the function argument in higher order's function signature - not from the ones used in the lambda's body as you suggest. So, `myfunc` will be declared as: void myfunc(string delegate(string x, string y)) { // ... And when the compiler see `myfunc({return "x:"~x~"y:"-y;});`, it'll see that `x` and `y` appear in the function argument's definition and match them accordingly. This means that `myfunc({/*...*/})` will be inferred to `myfunc((x,y) {/*...*/})` no matter what the order of argument usage in the lambda's body is - because in the function's signature the arguments are `x` and `y` in that order.
Sep 12 2015
On Saturday, 12 September 2015 at 10:44:05 UTC, Pierre Krafft wrote:On Saturday, 12 September 2015 at 03:32:51 UTC, Prudence wrote:I agree that they do conceal some things, but that is the nature of stuff. To claim it is wrong to do that is like saying auto is wrong because it too has the same issues. auto func() { return typeX; } later on, change it to typeY and then your screwed, it can also suffer from typos: auto func() { int t = 0; void *j; return j; // oops, typo, I meant t. } It just sounds like you are trying avoid all possible programmer faults... but that makes for weak programmers. Weaking the language for the lowest common denominator stagnates progress. Look out the American education system for a prime example. It's not the way to go, which has been proven time and time again. It's known as laziness. For me, I can look at the signature once and know the order and names. Regardless, no one is taking away your training wheels. I'm not saying replace the current syntax. I'm not sure why everyone pretends they are forced to use the syntactic sugar, If you have diabetes, don't use it!On Saturday, 12 September 2015 at 02:13:11 UTC, Pierre Krafft wrote:myfunc({return "x:"~x~"y:"-y;}); is infered to mean myfunc((x,y){return "x:"~x~"y:"-y;}); while myfunc({return "y:"~y~"x:"~x;}); is infered to mean myfunc((y,x){return "y:"~y~"x:"~x;}); which is not what I expect since the lambda I want is myfunc((x,y){return "y:"~y~"x:"~x;}); This can lead to subtle bugs which are very hard to see. In the typo example there could be two overloaded functions differing only in that one takes a delegate having 3 parameters and one taking a delegate having 4 parameters. If we explicitly write the lambda parameters the typo will be found since j is undefined. But when parameters are inferred the compiler will see that {return i*z + f*j;} matches the function taking a lambda with 4 parameters. Inferred parameter types are on the brink of what I can allow. They can risk typos, but not as easily since you write the parameters twice (declaration and usage). They can also silently change if the function taking the delegate has the parameter type changed. I don't want to add more magic to that area.On Saturday, 12 September 2015 at 01:03:54 UTC, Prudence wrote:What does this have to do with my proposal? Those issues exist regardless of the simplification. myfunc({return "x:"~x~"y:"-y;}) getting changed to myfunc({return "y:"~y~"x:"~x;}); huh? What do you mean the suggestion makes parameter usage order important? They are important, it has nothing to do with the suggestion? Are you saying that you want to reserve the right to do something like myfunc(string delegate(string x, string y)); and myfunc((y,x){ "y:"~y~"x:"~x; }) ? If so, or unless I'm missing something, that's bad no matter what. Changing the order and reversing the names is more than just confusing, it's hard to read and most people will gloss over that fact. Be consistent with your parameters and maybe you'll have less bugs? Or the typo in myfunc({return i*z+f*j;}); Again, what does this have to do with anything? A typo is a typo and is always a mistake. The above example has the same effect regardless if the parameters are explicit or deduced. myfunc((i,z,f) {return i*z+f*j;}); j is still a problem. If j is defined outside the lambda then regardless of specific or implicit parameter names, it will not cause any problems. In either case, the compiler can see that j is either referenced outside the scope or undefined. It has nothing to do with the parameters used. Of course maybe I'm missing something, but essentially are not almost all uses of lambda's simply copying the parameter signature of the delegate. It already infers types... you could say that leads to typo's too...On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli wrote:You're making your code more brittle for a small gain. The suggestion makes parameter usage order important and the compiler can't warn about my typos. Consider: myfunc({return "x:"~x~"y:"-y;}) getting changed to myfunc({return "y:"~y~"x:"~x;}); Or the typo in myfunc({return i*z+f*j;}); Lambdas are already very concise. This proposal doesn't give any benefits outside of very simple lambdas. Such lambdas are already so simple that they could use some standard functions instead (like sum, to!T, and bind).On 09/10/2015 10:55 AM, Prudence wrote:As I said, it could throw a warning or error. It, in some sense, is already a a problem with nested blocks that hide outside variables, is it not? The compiler doesn't need to scan anything. It knows the which parameters from the definition! -> void myfunc(double delegate(int i, int z, float f)) <- Compiler knows to use the names here as the default names in for the parameters when. when used: myfunc({ return i*z*f; }); <- Oh, there are the names, we know what they are because the signature is tells us. The compiler does the following: 1. Sees we have a block without any parameters defined. i.e., a lambda. 2. It looks up the signature of myfunc to find out what the names are 3. It sees that they are i z and f 4. Now it knows and it effectively rewrites the code as myfunc((i,z,f) { return i*z*f; }); Surely this is not difficult, 4 steps?How bout this: void myfunc(double delegate(int i, int z, float f)) {....} myfunc((int i, int z, float f) { return i*z*f; } } vs myfunc({ return i*z*f; }) // Names of parameters areinferred fromsignature.Considering other features of the language, that's pretty much impossible in D. What if there is another i in scope: int i; myfunc({ return i*z*f; }); Now, should it call another overload of myfunc that takes (int z, int f) because i is something else? Should the compiler analyze the body of the code and decide which symbols could be parameters? And then go through all overloads of myfunc? etc.? Ali
Sep 12 2015
On Thursday, 10 September 2015 at 17:55:06 UTC, Prudence wrote:Of course, this hides the names outside the lambda, but a warning could be issued(no different than if one does it explicitly.This makes the parameter names part of the API. The author of a library is unable to rename parameter without breaking user code. I do not believe the benefit is large enough to accept such a drawback.
Sep 10 2015
On Thursday, 10 September 2015 at 18:05:43 UTC, anonymous wrote:On Thursday, 10 September 2015 at 17:55:06 UTC, Prudence wrote:That's one of the main reasons that I hate the idea of named arguments. It's more stuff that's part of the API, more public stuff that you have to name correctly and risk bikeshedding arguments over, and more stuff that can you can't change without breaking existing code. - Jonathan M DavisOf course, this hides the names outside the lambda, but a warning could be issued(no different than if one does it explicitly.This makes the parameter names part of the API. The author of a library is unable to rename parameter without breaking user code. I do not believe the benefit is large enough to accept such a drawback.
Sep 10 2015
On Thursday, 10 September 2015 at 18:23:52 UTC, Jonathan M Davis wrote:On Thursday, 10 September 2015 at 18:05:43 UTC, anonymous wrote:+1On Thursday, 10 September 2015 at 17:55:06 UTC, Prudence wrote:That's one of the main reasons that I hate the idea of named arguments. It's more stuff that's part of the API, more public stuff that you have to name correctly and risk bikeshedding arguments over, and more stuff that can you can't change without breaking existing code. - Jonathan M DavisOf course, this hides the names outside the lambda, but a warning could be issued(no different than if one does it explicitly.This makes the parameter names part of the API. The author of a library is unable to rename parameter without breaking user code. I do not believe the benefit is large enough to accept such a drawback.
Sep 10 2015
On 09/10/2015 08:23 PM, Jonathan M Davis wrote:That's one of the main reasons that I hate the idea of named arguments. It's more stuff that's part of the API, more public stuff that you have to name correctly and risk bikeshedding arguments over, and more stuff that can you can't change without breaking existing code. - Jonathan M DavisNote that parameter names can already be determined by user code using reflection.
Sep 11 2015
On Friday, 11 September 2015 at 20:16:42 UTC, Timon Gehr wrote:On 09/10/2015 08:23 PM, Jonathan M Davis wrote:True, but as soon as you're doing much with reflection, all bets are off anyway, because it often becomes trivial to break code by making small changes. And I think that it's pretty clear at this point that you can't expect parameter names to not change, since they're not part of the function signature (even if compile-time reflection does let you get at them), which would not be the case if we had named arguments. - Jonathan M DavisThat's one of the main reasons that I hate the idea of named arguments. It's more stuff that's part of the API, more public stuff that you have to name correctly and risk bikeshedding arguments over, and more stuff that can you can't change without breaking existing code. - Jonathan M DavisNote that parameter names can already be determined by user code using reflection.
Sep 11 2015
On 2015-09-10 20:23, Jonathan M Davis wrote:That's one of the main reasons that I hate the idea of named arguments.In Ruby named arguments need to be explicitly requested when declaring a method: def bar(a) end def foo(a:) a == 3 end foo(a: 3) bar(a: 3) Not supplying the name of the parameter in the call to "foo" would result in an error. I think named arguments like this is way, _way_ more superior that the ridiculous idea of using an enum instead of a bool. -- /Jacob Carlborg
Sep 12 2015
On Saturday, 12 September 2015 at 14:40:05 UTC, Jacob Carlborg wrote:Not supplying the name of the parameter in the call to "foo" would result in an error.Python has similar semantics. Very useful to force explicitness when you have complex changing APIs that have many parameters of the same type "add_row(string,string,string,string,string,string)" But it is a bit different than using named variables in a lambda, since in the lambda case it will shadow local variables.
Sep 12 2015
On Thursday, 10 September 2015 at 17:55:06 UTC, Prudence wrote:by specifying the parameter names in the signature, we don't have to specify them in the lamba creation. This doesn't replace the original way, just adds the ability to infer the names if they are not specified. Of course, this hides the names outside the lambda, but a warning could be issued(no different than if one does it explicitly.How about just having numbered parameters like this: { $2 < ($1*$2) }
Sep 10 2015
On Thursday, 10 September 2015 at 19:37:53 UTC, Ola Fosheim Grøstad wrote:How about just having numbered parameters like this: { $2 < ($1*$2) }What about this situation? [[1, 2], [3, 4], [5, 6]].reduce!{ auto localMax = { $1 > $2 ? $1 : $2; } auto first = $1.reduce!localMax; auto second = $2.reduce!localMax; return first > second ? first : second; } How can the compiler tell which $1 and $2 is which? What if one wants to access both the outer $1 and the inner $1 in localMax?
Sep 10 2015
On Thursday, 10 September 2015 at 20:10:49 UTC, Meta wrote:On Thursday, 10 September 2015 at 19:37:53 UTC, Ola Fosheim Grøstad wrote:Should be `return first > second ? $1 : $2`, but you get the idea.How about just having numbered parameters like this: { $2 < ($1*$2) }What about this situation? [[1, 2], [3, 4], [5, 6]].reduce!{ auto localMax = { $1 > $2 ? $1 : $2; } auto first = $1.reduce!localMax; auto second = $2.reduce!localMax; return first > second ? first : second; } How can the compiler tell which $1 and $2 is which? What if one wants to access both the outer $1 and the inner $1 in localMax?
Sep 10 2015
On Thursday, 10 September 2015 at 20:10:49 UTC, Meta wrote:How can the compiler tell which $1 and $2 is which? What if one wants to access both the outer $1 and the inner $1 in localMax?If there is a conflict you should use a regular lambda on the outer one?
Sep 10 2015
On Thursday, 10 September 2015 at 20:56:58 UTC, Ola Fosheim Grøstad wrote:If there is a conflict you should use a regular lambda on the outer one?You could, but then doesn't that defeat the point a bit? My example was off-the-cuff, but the point is that we already have a fairly concise lambda syntax, and adding a new type will mean that we have 4 different ways of expressing the same lambda function. It's just not really worth it.
Sep 10 2015
On Thursday, 10 September 2015 at 21:03:12 UTC, Meta wrote:On Thursday, 10 September 2015 at 20:56:58 UTC, Ola Fosheim Grøstad wrote:Yes, it is usually it is a bad idea to have many ways to do things. A numbered schema probably should only be used in an innermost scope as a single expression, so if you see "$1" you know the definition stops at the brackets. Apropos one way of doing things: http://www.ozonehouse.com/mark/periodic/ :DIf there is a conflict you should use a regular lambda on the outer one?You could, but then doesn't that defeat the point a bit? My example was off-the-cuff, but the point is that we already have a fairly concise lambda syntax, and adding a new type will mean that we have 4 different ways of expressing the same lambda function. It's just not really worth it.
Sep 10 2015
On Thursday, 10 September 2015 at 21:03:12 UTC, Meta wrote:On Thursday, 10 September 2015 at 20:56:58 UTC, Ola Fosheim Grøstad wrote:Clojure solved this by disallowing nesting lambdas-with-numbered-arguments: Clojure 1.7.0 3 clojure.lang.LispReader$FnReader.invoke (LispReader.java:703) #object[clojure.core$_PLUS_ 0x10fde30a "clojure.core$_PLUS_ 10fde30a"] CompilerException java.lang.RuntimeException: Unable to resolve symbol: %1 in this context, compiling:(NO_SOURCE_PATH:0:0) CompilerException java.lang.RuntimeException: Unable to resolve symbol: %2 in this context, compiling:(NO_SOURCE_PATH:0:0) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:221) CompilerException java.lang.RuntimeException: Unable to resolve symbol: %2 in this context, compiling:(NO_SOURCE_PATH:0:0) CompilerException java.lang.RuntimeException: Unable to resolve symbol: %1 in this context, compiling:(NO_SOURCE_PATH:0:0) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:221) 1 2 RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:221) Than again, Clojure never was a big advocate of the one-way-of-doing-things approach... At any rate, since string lambdas can usually be used in place of this syntax, and in the cases string lambdas can't be used(because you need something from the scope) it's not THAT hard to use proper lambdas - I see no reason to support it.If there is a conflict you should use a regular lambda on the outer one?You could, but then doesn't that defeat the point a bit? My example was off-the-cuff, but the point is that we already have a fairly concise lambda syntax, and adding a new type will mean that we have 4 different ways of expressing the same lambda function. It's just not really worth it.
Sep 10 2015
On 2015-09-10 23:03, Meta wrote:You could, but then doesn't that defeat the point a bit?No, I don't think it does. For example in Scala you can do like this: foo(_ < _) Which would be the same as: foo((a, b) a < b) But if you want to use the same parameter more than once then you cannot use the first syntax. -- /Jacob Carlborg
Sep 12 2015
On Thursday, 10 September 2015 at 19:37:53 UTC, Ola Fosheim Grøstad wrote:How about just having numbered parameters like this: { $2 < ($1*$2) }The string lambdas Phobos supports basically does this: `b < a*b` would work in there. These are falling out of favor with the new syntax in the language, but they are still supported by most the library.
Sep 10 2015
On Thursday, 10 September 2015 at 20:51:18 UTC, Adam D. Ruppe wrote:The string lambdas Phobos supports basically does this: `b < a*b` would work in there. These are falling out of favor with the new syntax in the language, but they are still supported by most the library.Isn't that a string mixin? Or?
Sep 10 2015
On Thu, 2015-09-10 at 20:51 +0000, Adam D. Ruppe via Digitalmars-d wrote:[=E2=80=A6] =20 The string lambdas Phobos supports basically does this: =20 `b < a*b` =20 would work in there. These are falling out of favor with the new=20 syntax in the language, but they are still supported by most the=20 library.And until some bugs get fixed, you have to use string functions in some places, you cannot use proper function literals :-( --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Sep 11 2015
On Friday, 11 September 2015 at 08:02:21 UTC, Russel Winder wrote:On Thu, 2015-09-10 at 20:51 +0000, Adam D. Ruppe via Digitalmars-d wrote:Can you elaborate? Are those bugs logged somewhere?[…] The string lambdas Phobos supports basically does this: `b < a*b` would work in there. These are falling out of favor with the new syntax in the language, but they are still supported by most the library.And until some bugs get fixed, you have to use string functions in some places, you cannot use proper function literals :-(
Sep 11 2015
On Fri, 2015-09-11 at 11:32 +0000, ZombineDev via Digitalmars-d wrote:On Friday, 11 September 2015 at 08:02:21 UTC, Russel Winder wrote:For example https://issues.dlang.org/show_bug.cgi?id=3D5710 The affects a number of the std.parallelism functions :-( --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winderOn Thu, 2015-09-10 at 20:51 +0000, Adam D. Ruppe via=20 Digitalmars-d wrote:=20 Can you elaborate? Are those bugs logged somewhere?[=E2=80=A6] =20 The string lambdas Phobos supports basically does this: =20 `b < a*b` =20 would work in there. These are falling out of favor with the=20 new syntax in the language, but they are still supported by=20 most the library.=20 And until some bugs get fixed, you have to use string functions=20 in some places, you cannot use proper function literals :-(
Sep 11 2015
On Friday, 11 September 2015 at 11:44:13 UTC, Russel Winder wrote:For example https://issues.dlang.org/show_bug.cgi?id=5710If C++ interop is still important, maybe it would be a good idea to adopt C++ style lambdas.
Sep 11 2015
On Friday, 11 September 2015 at 20:25:19 UTC, Ola Fosheim Grøstad wrote:On Friday, 11 September 2015 at 11:44:13 UTC, Russel Winder wrote:How would that help with interop? Even if we supported passing a lambda to C++ code, the syntax wouldn't need to match, just the semantics, and that could be done without adopting C++ style lambdas in D. However, given the complexity of C++ templates, as I understand it, there are no plans to ever support them in C++ interop (since it would pretty much mean putting a C++ compiler in the D compiler), in which case, there's no need to worry about C++ lambdas anyway, because they all involve templates. So, while C++ interop is important, and it's gotten some major improvements in the process of switching to D for the compiler front-end (and will likely continue to get improvements), there are still some pretty severe limits on what we're going to be able to do if we don't want to put a full C++ compiler inside of the D compiler, and we really don't want to be doing that. - Jonathan M DavisFor example https://issues.dlang.org/show_bug.cgi?id=5710If C++ interop is still important, maybe it would be a good idea to adopt C++ style lambdas.
Sep 11 2015
On Friday, 11 September 2015 at 23:15:58 UTC, Jonathan M Davis wrote:style lambdas in D. However, given the complexity of C++ templates, as I understand it, there are no plans to ever support them in C++ interop (since it would pretty much mean putting a C++ compiler in the D compiler), in which case, there's no need to worry about C++ lambdas anyway, because they all involve templates.No, you have to generate c++ sourcecode. No need to build in the compiler.
Sep 11 2015