Nested Functions: C# that looks like Javascript
Introduction
Anonymous functions and closures are a language feature that, in many ways, allow programmers to reshape the syntax of a language. Although often associated with highly dynamic languages such as Lisp and TCL and moderately dynamic languages, such as Javascript, C# shows that closures retain their power in statically typed languages. In this article, I identify a language feature that I like from the Pascal language and ‘clone’ it using closures in C#.
Nested Functions in Pascal
Pascal (a historically important teaching language that’s as statically typed as you can get) allows programmers to define a named function inside the scope of an enclosing function. This is a mechanism for encapsulation, much like the mechanisms of object-oriented programming. Here’s an example of how nested functions work in Pascal, borrowed from Wikipedia:
01 function E(x: real): real; 02 function F(y: real): real; 03 begin 04 F := x + y 05 end; 06 begin 07 E := F(3) 08 end;
Note that you return values in Pascal by assigning to a ‘variable’ with the same name as the function. The F function is nested inside E, so (i) F can only be called inside function E and (ii) F has access to variables defined inside function E. Now, this example is contrived (it’s an obfuscated way to write E(x)=x+3, but this is a useful tool if you’ve got a chunk of code that is reused several times inside a function.
Nested Functions in C#
Although C# doesn’t explicitly support nested functions, it’s easy to simulate this feature using an anonymous function (a lambda.) To do this, I use an idiom which is common in Javascript, the naming of an anonymous function by assigning it to a named variable:
09 static double E(double x) { 10 Func<double,double> F = (double y) => x+y; 11 return F(3.0); 12 }
But why?
I was writing an algorithm over trees the other day, and noticed that there was a chunk of code that I was repeating in multiple places inside a single function; as this chunk was increasing in complexity, I felt alarmed by the duplication. I could have spun the “inner” function into a named method of the class the “outer” function was in, but that would have meant moving certain variables out of method scope into class scope — I didn’t like this, because the rest of the class had no business accessing these variables.
I could have split out the tree algorithm into a separate class, but that bulks up the code and creates more artifacts to maintain. Splitting the algorithm into a separate class might let me enable reuse by adding extension points and using the Visitor pattern, but I could have ended up creating an interface and several new classes… while never getting around in the future to take advantage of that promised reuse.
Object-functional languages like C# offer programmers new choices when it comes to encapsulation, inheritance and reuse: the study of patterns and idioms used in languages such as LISP and Javascript can be fruitful for the C# programmer, and proves that the many of the strengths that people associate with dynamically typed languages can be enjoyed in statically typed languages.
Paul Houle on May 14th 2010 in Asynchronous Communications