Higher-order functions?

Timon Gehr timon.gehr at gmx.ch
Tue Apr 10 17:03:04 PDT 2012


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)





More information about the Digitalmars-d-learn mailing list