What does alias do?
ag0aep6g via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Apr 27 14:03:38 PDT 2016
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.
More information about the Digitalmars-d-learn
mailing list