Thursday, 20 January 2011

Python Closures and Currying

A closure is a function that can be customized due to bound variables (easily done using objects). If currying is applied then is a function that remembers and reuse the result of its previous execution and/or the arguments previously passed.
class sorter():
  def __init__(self,reverse=None):
    self.reverse = reverse or False
    self.result = []
  def __call__(self,target,reverse=None):
    self.reverse = reverse if reverse is not None else self.reverse
    self.result += target
    return sorted(self.result,reverse=self.reverse)

This function is a closure:
In [8]:l = [1,4,65,2,3]
In [9]:sorter(True)(l)
Out[9]:[65, 4, 3, 2, 1]
In [10]:sorter(False)(l)
Out[10]:[1, 2, 3, 4, 65]

And also applies currying:
In [30]:s = sorter(True)
In [31]:s(l)
Out[31]:[65, 4, 3, 2, 1]
In [32]:s([6,7,8],False)
Out[32]:[1, 2, 3, 4, 6, 7, 8, 65]
In [33]:s([1,65,8])
Out[33]:[1, 1, 2, 3, 4, 6, 7, 8, 8, 65, 65] 
 
Other types of currying closures use sequential argument initialization (each setter method returns self):
result = function.setArg1(x).setArg2(y).setArg3(3).calculate()

Partial doesn't work fine with this kind of closures, as partial doesn't propagate inner attributes of the function object.
I way to implement curry closures could use call(self,*args,**kw) to manage argument identification.

No comments:

Post a Comment