Delegates, Closures and Lambdas
19.1 Function Pointers vs Delegates
int twice(int x) { return x * 2; }
int function(int) fp = &twice; // no context
int factor = 3;
int delegate(int) dg = (int x) => x * factor; // captures a context (closure)
writeln(fp(5), " ", dg(5));19.2 Closures
scope delegates (e.g., void run(scope void delegate() dg)) avoid heap allocation.
auto makeCounter()
{
int count = 0;
return () => ++count; // captures `count`; the frame is moved to the GC heap
}
auto c = makeCounter();
writeln(c(), c(), c()); // 1 2 319.3 Lambda Syntax
auto add = (int a, int b) => a + b;
auto sq = (x) { return x * x; }; // template lambda (parameter type inferred at the call)
auto alt = delegate(int x) { return x; };
import std.algorithm : map;
[1, 2, 3].map!(x => x * x);
[1, 2, 3].map!"a * a"; // string lambda (legacy but common)19.4 Higher-Order Functions and std.functional
import std.functional;
alias inc = (int x) => x + 1;
alias dbl = (int x) => x * 2;
alias incThenDbl = compose!(dbl, inc); // dbl(inc(x))
alias pipeline = pipe!(inc, dbl); // inc then dbl
writeln(incThenDbl(3), pipeline(3));
alias add5 = partial!((int a, int b) => a + b, 5);
auto fastFib = memoize!fib; // memoization
auto neg = not!(x => x > 0);
auto swapped = binaryReverseArgs!((a, b) => a - b);