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.