// Delegates (higher-order functions) in C# (2.0 or higher) /* A "delegate" in C# is type for lambda terms that can be manipulated as values. This mechanism is a good example of how modern programming languages are converging: what once was strictly the domain of languages such as scheme are now finding their way into more conventional languages. This feature was initially introduced in the first version of C# and then vastly expanded in C# 2.0 (aka C# 2005). */ using System; using System.Collections.Generic; // needed for List class public delegate int fun(int x); // declares delegate type public delegate int fun2(int x, int y); public delegate bool predicate(int x); public class higherorder // main class { // instances of delegates public static int square(int x) { return x*x; } public static int mult(int x, int y) { return x*y; } public static bool odd(int x) { return x%2==1; } // higher order function to map a funtion over every element of a List public static List map(fun f, List M) { List A = new List(); foreach (int x in M) { A.Add( f(x) ); } // can also use other loop structures: // for (int i=0;i filter(predicate p, List M) { List N = new List(); // new list to be constructed foreach (int x in M) { if (p(x)) N.Add(x); } return N; } // filter // The following "function" illustrates how the "closures" of scheme/perl can // also be captured in C# using delegates: public static fun makeaccumulator(int init) // returns a fun delegate { int ax = init; // the accumulator closure variable return delegate(int x) { ax += x; return ax; }; } // makeaccumulator public static void Main(string[] args) { List L = new List(); // List is a typed array/list combo structure L.Add(2); L.Add(3); L.Add(5); L.Add(7); L.Add(10); List M = map(new fun(square), L); foreach (int x in M) Console.Write(x+" "); // prints 4 9 24 9 25 49 100 Console.WriteLine(""); // in-line delegate (like an anonymous lambda term (sub in perl)) // "delegate" here is like a typed lambda: M = filter( delegate(int x) {return x%2==0;}, L); // filter even elements foreach (int x in M) Console.Write(x+" "); // prints 2 10 Console.WriteLine("\n\n"); // closures in C#: fun myax = makeaccumulator(0); fun yourax = makeaccumulator(100); Console.WriteLine(myax(50)); Console.WriteLine(myax(50)); Console.WriteLine(yourax(50)); } // main } // class higherorder