Re: Better lambdas!!!!!!!!!!

2015-09-12 Thread Prudence via Digitalmars-d
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 

Re: Better lambdas!!!!!!!!!!

2015-09-12 Thread Ola Fosheim Grostad via Digitalmars-d
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.




Re: Better lambdas!!!!!!!!!!

2015-09-12 Thread Pierre Krafft via Digitalmars-d

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.


Re: Better lambdas!!!!!!!!!!

2015-09-12 Thread Jacob Carlborg via Digitalmars-d

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)
  a == { a: 3 } # A hash (associative array)
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


Re: Better lambdas!!!!!!!!!!

2015-09-12 Thread Jacob Carlborg via Digitalmars-d

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


Re: Better lambdas!!!!!!!!!!

2015-09-12 Thread via Digitalmars-d
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.





Re: Better lambdas!!!!!!!!!!

2015-09-12 Thread Idan Arye via Digitalmars-d
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.


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Russel Winder via Digitalmars-d
On Thu, 2015-09-10 at 20:51 +, 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 :-(

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



signature.asc
Description: This is a digitally signed message part


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Timon Gehr via Digitalmars-d

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.


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread via Digitalmars-d

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.




Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Jonathan M Davis via Digitalmars-d
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


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Jonathan M Davis via Digitalmars-d

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


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread ZombineDev via Digitalmars-d

On Friday, 11 September 2015 at 08:02:21 UTC, Russel Winder wrote:
On Thu, 2015-09-10 at 20:51 +, 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?


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Russel Winder via Digitalmars-d
On Fri, 2015-09-11 at 11:32 +, 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 +, 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?

For example https://issues.dlang.org/show_bug.cgi?id=5710

The affects a number of the std.parallelism functions :-(

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder



signature.asc
Description: This is a digitally signed message part


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Prudence via Digitalmars-d

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?




Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Pierre Krafft via Digitalmars-d

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).


Re: Better lambdas!!!!!!!!!!

2015-09-11 Thread Prudence via Digitalmars-d
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...






Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Ali Çehreli via Digitalmars-d

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



Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread anonymous via Digitalmars-d

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.


Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Idan Arye via Digitalmars-d

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
user=> (#(+ %1 %2) 1 2)
3
user=> (#(#(+ %1 %2) %2 %1) 1 2)
IllegalStateException Nested #()s are not allowed  
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.


Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread wobbles via Digitalmars-d
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


Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread via Digitalmars-d

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) }




Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Meta via Digitalmars-d
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?


Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Meta via Digitalmars-d

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.


Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Adam D. Ruppe via Digitalmars-d
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.


Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread via Digitalmars-d
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?



Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread via Digitalmars-d

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?




Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Meta via Digitalmars-d
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.


Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread via Digitalmars-d

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



Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Adam D. Ruppe via Digitalmars-d

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.




Re: Better lambdas!!!!!!!!!!

2015-09-10 Thread Jonathan M Davis via Digitalmars-d

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