Closures in Python

December 18th 2010

I don’t exactly make my sexy-times love affair with Lisp a secret. Imperative languages have their strengths, but I love my functional programming perks.

I’ve recently started seriously digging into Python, though, and I think it’s going to be the Imperative Language That Makes Me Cry The Least. It’s got the holy higher-order trinity of map, reduce, and filter, syntactically-sugary list comprehensions, lambda expressions, and it even uses ** as the exponentiation operator, as God and Fortran intended.1 It also has closures, which are magic if you haven’t seen them before, so I’m going to yammer on about them for a bit.

To be fair, I’m probably not the best person in the world to tell you about lexical closures. You really want Wikipedia. In brief, though, a closure is a function that can access state in the scope in which it was defined. An example would probably be clearest:2

def make_power_fn(power):
     def power_fn(base):
         return base ** power
     return powerFn

cube = make_power_fn(3)
print map(cube, [1, 2, 3, 4, 5])

Executing the above code applies our cube function to every item in the list and prints out [1, 8, 27, 64, 125].3 Neat, right? The magic part is that cube was effectively able to access power because it was defined within the enclosing lexical scope.

The concept of closures is pretty deeply embedded in serious-business functional languages like Haskell and the various dialects of Lisp,4 but lots of relatively modern mostly-imperative languages like Ruby and JavaScript have adopted them, too. I seem to recall that there’s been a ongoing attempt to get closures into Java, but I’ll believe that when I see it.

Anyway, closures! Now you know!


1 Python still can’t make real metaprogramming trivial the way Lisp does, though. But it’s about as good as it can be without actually being it’s own abstract syntax tree.
2 Example adapted from defmacro’s very nice functional programming discussion (near the bottom).
3 Notice how I got to use both map and ** in there? Awww, yeah.
4 “Haskell and the Lisps” would be an awesome band name, you guys.