Tuesday, February 20, 2007

Closures

Dustin Campbell has written a great series over the past few weeks on functional programming topics, which despite being a classic computer science topic, tends to be a little bit ahead of the curve as far as modern day .NET programming is concerned (that will all change in the near future, though - trust me!).

"Closures" is one of the topics that both he and Bill Wagner are expressing a lot of passion for these days, because understanding what they are and how they work are a critical as we move forward into everyday acceptance of Anonymous Methods, Lambda Expressions, and scary things like that.

I've had a pretty good understanding of what a Closure was up to this point, thanks mostly to seeing Dustin present on the topic, as well as spending six hours trapped in a car with him as we drove to and from Dayton one evening.  However, I read something today that really made it click.

I was reading up on the programming language LUA, which just happens to be used to create add-on modules for World of Warcraft (wink, wink).  LUA is a dynamically typed language that supports using functions as first-class variables.  It also supports the concept of anonymous/inline functions, as demonstrated by the following:

function makeaddfunc(x)
-- Return a new function that adds x to the argument
return function(y)
-- When we refer to the variable x, which is outside of the current
-- scope and whose lifetime is shorter than that of this anonymous
-- function, Lua creates a closure.
return x + y
end
end
plustwo = makeaddfunc(2)
print(plustwo(5)) -- Prints 7

(Credit: http://en.wikipedia.org/wiki/Lua_programming_language)


From that Wikipedia article comes this quote, which resulted in my "ah-ha!" moment:



A new closure for the variable x is created every time makeaddfunc is called, so that the anonymous function returned will always access its own x parameter. The closure is managed by Lua's garbage collector, just like any other object.


So, the simplified point is that because makeaddfunc(x) contains an anonymous function that uses "x", a closure is created each time that makeaddfunc(x) is called in order to preserve the state of variables that are defined outside of the scope of the anonymous function.


I'm not sure if this will help to clear things up for other people as well as it did for me, but here's hoping!