www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Better lambdas!!!!!!!!!!

reply "Prudence" <Pursuit Happyness.All> writes:
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
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
parent reply "Prudence" <Pursuit Happyness.All> writes:
On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli wrote:
 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
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?
Sep 11 2015
parent reply "Pierre Krafft" <kpierre+dlang outlook.com> writes:
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:
 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
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?
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).
Sep 11 2015
parent reply "Prudence" <Pursuit Happyness.All> writes:
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:
 On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli 
 wrote:
 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
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?
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).
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...
Sep 11 2015
parent reply "Pierre Krafft" <kpierre+dlang outlook.com> writes:
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:
 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:
 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
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?
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).
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...
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.
Sep 12 2015
next sibling parent "Idan Arye" <GenericNPC gmail.com> writes:
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
prev sibling parent "Prudence" <Pursuit Happyness.All> writes:
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:
 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:
 On Thursday, 10 September 2015 at 18:02:36 UTC, Ali Çehreli 
 wrote:
 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
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?
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).
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...
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.
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!
Sep 12 2015
prev sibling next sibling parent reply "anonymous" <a b.cd> writes:
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
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, 10 September 2015 at 18:05:43 UTC, anonymous wrote:
 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.
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 Davis
Sep 10 2015
next sibling parent "wobbles" <grogan.colin gmail.com> writes:
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:
 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.
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 Davis
+1
Sep 10 2015
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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 Davis
Note that parameter names can already be determined by user code using reflection.
Sep 11 2015
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Friday, 11 September 2015 at 20:16:42 UTC, Timon Gehr wrote:
 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 Davis
Note that parameter names can already be determined by user code using reflection.
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 Davis
Sep 11 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
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
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
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
prev sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
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
next sibling parent reply "Meta" <jared771 gmail.com> writes:
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
next sibling parent "Meta" <jared771 gmail.com> writes:
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:
 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?
Should be `return first > second ? $1 : $2`, but you get the idea.
Sep 10 2015
prev sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
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
parent reply "Meta" <jared771 gmail.com> writes:
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
next sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
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:
 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.
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/ :D
Sep 10 2015
prev sibling next sibling parent "Idan Arye" <GenericNPC gmail.com> writes:
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:
 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.
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.
Sep 10 2015
prev sibling parent Jacob Carlborg <doob me.com> writes:
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
prev sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
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
next sibling parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
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
prev sibling parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
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
parent reply "ZombineDev" <valid_email he.re> writes:
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:
 […]
 
 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 :-(
Can you elaborate? Are those bugs logged somewhere?
Sep 11 2015
parent reply Russel Winder via Digitalmars-d <digitalmars-d puremagic.com> writes:
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:
 On Thu, 2015-09-10 at 20:51 +0000, Adam D. Ruppe via=20
 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=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 :-(
=20 Can you elaborate? Are those bugs logged somewhere?
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_winder
Sep 11 2015
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Friday, 11 September 2015 at 11:44:13 UTC, Russel Winder wrote:
 For example https://issues.dlang.org/show_bug.cgi?id=5710
If C++ interop is still important, maybe it would be a good idea to adopt C++ style lambdas.
Sep 11 2015
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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:
 For example https://issues.dlang.org/show_bug.cgi?id=5710
If C++ interop is still important, maybe it would be a good idea to adopt C++ style lambdas.
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 Davis
Sep 11 2015
parent "Ola Fosheim Grostad" <ola.fosheim.grostad+dlang gmail.com> writes:
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