On 04/11/2012 01:13 AM, Jonas H. wrote:
Hi everyone,
does D have any runtime higher-order function facilities?
D has full runtime support for higher-order functions and closures.
import std.stdio;
int[] map(scope int delegate(int) f, int[] a){
auto b = new int[a.length];
foreach(i,x;a) b[i] = f(x);
return b;
}
void main(){
int a = 2;
writeln(map(x=>a*x, [1,2,3]));
}
(I'm not talking about templates.)
You will often use templates together with runtime higher order
functions. Eg:
import std.stdio;
T[] map(T,S)(scope T delegate(S) f, S[] a){
auto b = new T[a.length];
foreach(i,x;a) b[i] = f(x);
return b;
}
void main(){
int a = 2;
writeln(map((int x)=>a*x, [1,2,3]));
writeln(map((double x)=>a*x, [1.6,2.7,3.8]));
}
For function literals that contain more than one statement, there is an
alternate syntax:
auto dg = (int a, double b){a*=b; return a+b;}
You can explicitly specify 'function' or 'delegate':
auto fp = function (int x) => 2*x; // not a closure, simple function
pointer (uses less space, but is less powerful)
int a = 2;
auto dg = delegate (int x) => a*x; // closure, can refer to a
You can leave out argument types when they can be directly deduced from
the context.
Finally, if the literal has an explicit 'function' or 'delegate' it is
possible to explicitly specify the return type:
auto dg = delegate int(int x) => x;
More specifically, is something like this possible? (That's how I'd do
it in Python)
car_prices = map(Car.get_price, list_of_cars)
car = new Car
foobar(car.get_price)
Thanks
Jonas
(Well, the standard way to do what that python code does is using templates.
auto car_prices = map!(car => car.get_price)(list_of_cars);// lazy range
auto car_prices = array(map!(car => car.get_price(list_of_cars)); //
eager array)