On Tue, 30 Nov 2010 18:49:56 +0300, Dmitry Olshansky wrote: > On 30.11.2010 14:59, Lars T. Kyllingstad wrote: >> In my library I have a lot of functionals (functions that take other >> functions as parameters). Here is an example that shows the style I >> use to define them: >> >> // Example: Evaluate the function/delegate/functor f at x. auto >> eval(F, X)(F f, X x) { return f(x); } >> >> // Test >> void main() >> { >> int add2(int i) { return i + 2; } >> assert (eval(&add2, 1) == 3); >> } >> >> In other words, the function is passed as a run-time parameter. I've >> seen this (or similar) style used in Phobos, but there, I've also noted >> that functions are sometimes passed as template alias parameters: >> >> // Same as above, using template alias parameter. auto eval(alias >> f, X)(X x) { return f(x); } >> >> // Test >> void main() >> { >> int add2(int i) { return i + 2; } >> assert (eval!add2(1) == 3); >> } >> >> I'd be grateful if people would share their knowledge of the pros and >> cons of each method. For instance, are there any situations where >> template alias parameters don't work? >> >> >> Thanks, >> >> -Lars > alias parameters must be know/computable at compile time, quick example > on what you can't do: > > import std.stdio; > > auto eval(F, X)(F f, X x) { return f(x); } auto eval2(alias f,X)(X x){ > return f(x); } > > auto summator(int k){ > int f(int val){ > return k + val; > } > return &f; > } > > > // Test > void main() > { > int add2(int i) { return i + 2; } > int traceAdd2(int i){ > writeln(i," --> ",i+2); > return i+2; > } > int delegate(int) getAdd2(){ > writeln("Getting add2"); > return &add2; > } > assert(eval(&add2, 1) == 3); > assert(eval2!add2(1) == 3); > assert(eval(summator(2),1) == 3); > //Next one fails with > //Error: closures are not yet supported in CTFE //Error: cannot > evaluate summator(2) at compile time > //assert(eval2!(summator(2))(1) == 3); > > assert(eval(&traceAdd2,1) == 3); > assert(eval2!traceAdd2(1) == 3); //side effect in call is no > problem > > assert(eval(getAdd2,1) == 3); > //Next one fails with > //Error: cannot evaluate writeln("Getting add2") at compile time > //Error: cannot evaluate getAdd2() at compile time > //assert(eval2!(getAdd2())(1) == 3); > }
That's a very good point, and pretty much settles it for me. I'll stay away from alias parameters, then. Thanks! -Lars