Better lambdas!!!!!!!!!!

Prudence via Digitalmars-d digitalmars-d at puremagic.com
Sat Sep 12 10:09:58 PDT 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:
>> 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!




More information about the Digitalmars-d mailing list