Here is an example from Python's standard library, inspect.py. It currently reads
def strseq(object, convert, join=joinseq):
"""Recursively walk a sequence, stringifying each element."""
if type(object) in (list, tuple):
return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object))
else:
return convert(object)
This has, as parameters, a convert function and a join function, and recursively walks over lists and tuples. The recursion is implemented using map(), where the first parameter is a function. The code predates the support for closures in Python, so needs two additional default arguments, to pass convert and join into the recursive call. With closures, this reads
def strseq(object, convert, join=joinseq):
"""Recursively walk a sequence, stringifying each element."""
if type(object) in (list, tuple):
return join(map(lambda o: strseq(o, convert, join), object))
else:
return convert(object)
In OO languages, you typically don't use closures too often, as you can use objects to pass state - and bound methods, when your language has them. When Python didn't have closures, people said that Python emulates closures with objects, whereas Lisp emulates objects with closures. As an example from IDLE (ClassBrowser.py):
class ClassBrowser: # shortened
def close(self, event=None):
self.top.destroy()
self.node.destroy()
def init(self, flist):
top.bind("<Escape>", self.close)
Here, self.close is a parameter-less callback invoked when Escape is pressed. However, the close implementation does need parameters - namely self, and then self.top, self.node. If Python didn't have bound methods, you could write
class ClassBrowser:
def close(self, event=None):
self.top.destroy()
self.node.destroy()
def init(self, flist):
top.bind("<Escape>", lambda:self.close())
Here, the lambda would get "self" not from a parameter, but from the context.