On 27.04.2016 21:40, xtreak wrote:
import std.array;
import std.range;
import std.algorithm;
import std.stdio;

T test(alias f, T)(T num) {
   return f(num);
}

T test1(T, V)(T num, V f){
     return f(num);
}

void main() {
   writeln("hello world");
   writeln(10000.iota
           .map!(a => a * a)
           .take(5));
   writeln(test!(z => z * z)(10));
   writeln(test1(10, ((z) => z *z)));
   writeln(test1(10, function int(int z) { return z * z; }));
}

What is the difference between passing as alias and then passing it as
lambda. Does it involve any cost.

As far as I understand, you can imagine `z => z * z` being pasted for `f` in the alias version. That is, for `test!(z => z * z)(10)` a function `int test(int num) {return (z => z * z)(num);}` is generated. It should be easy for the compiler/optimizer to turn that into `return z * z;`.

When `f` is a function parameter, a function pointer / delegate is passed at run-time, unless the optimizer manages to inline it. I don't know how good/aggressive inliners are and if they fail to do this in practice.

Also note that the alias version generates a new function for every f. The function parameter version only generates one function per `typeof(f)`.

Also the second form of short notation
throws an error that it returns void.

This line, right?

  writeln(test1(10, ((z) => z *z)));

That doesn't work because both the type of test1's V and the type of z are generic. For example, z could be int or float, and V could be `int function(int)` or `float function(float)`. The compiler can't decide that, so it errors out.

Either z or the type of f need to be more explicit. These are ok:
----
writeln(test1(10, (int z) => z * z)); /* now V can be deduced as int function(int) */

T test2(T)(T num, T function(T) f){ /* building f's type from T */
    return f(num);
}
writeln(test2!int(10, z => z * z)); /* giving T explicitly */
----

The alias version doesn't have this problem because `z => z * z` is just pasted in there. z's type doesn't matter until the call is analyzed. And then num's type is known which forces z's type.

Reply via email to