Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

objects or closures - when to use?

I can define an object and assign attributes and methods:

class object:
    def __init__(self,a,b):
        self.a = a
        self.b = b
    def add(self):
        self.sum = self.a + self.b
    def subtr(self):
        self.fin = self.sum - self.b
    def getpar(self):
        return self.fin

obj = object(2,3)
obj.add()
obj.subtr()
obj.getpar()

or provide the same functionality by defining a closure:

def closure(a,b):
    par = {}
    def add():
        par.update({'sum':a+b})
    def subtr():
        par.update({'fin':par['sum']-b})
    def getpar():
        return par['fin']
    return {'add':add,'subtr':subtr,'getpar':getpar}

clos = closure(2,3)
clos['add']()
clos['subtr']()
clos['getpar']()

I think the object syntax would look cleaner to most viewers, but are there instances in which the use of a closure would be semantically preferable?

like image 582
hatmatrix Avatar asked Jul 05 '10 23:07

hatmatrix


People also ask

When should closures be used?

Closures are frequently used in JavaScript for object data privacy, in event handlers and callback functions, and in partial applications, currying, and other functional programming patterns.

What is closure and when should you use it?

In JavaScript, a closure is a function that references variables in the outer scope from its inner scope. The closure preserves the outer scope inside its inner scope. To understand the closures, you need to know how the lexical scoping works first.

Why would you use a closure?

Closures are useful because they let you associate data (the lexical environment) with a function that operates on that data. This has obvious parallels to object-oriented programming, where objects allow you to associate data (the object's properties) with one or more methods.

Are closures like objects?

If you come from a FP background, you might find thinking in terms of closures more natural, and may therefore think of them as a more fundamental concept than objects. Moral of the story is that closures and objects are ideas that are expressible in terms of each other, and none is more fundamental than the other.


1 Answers

You should use the version that most clearly expresses what you are trying to achieve.

In the example given, I'd say that object version is more clear, since it seems to be modeling an object with state that changes. Looking at the code that uses the value, the object version seems to express the clear intent, whereas the closure version seems to have operations (the indexing and 'magic' strings) that are beside the point.

In Python, I would favor a closure based approach when what is needed is something that is mostly like a function, and perhaps needs to capture some state.

def tag_closure(singular, plural):
    def tag_it(n):
        if n == 1:
            return "1 " + singular
        else:
            return str(n) + " " + plural
    return tag_it

t_apple = tag_closure("apple", "apples")
t_cherry = tag_closure("cherry", "cherries");
print t_apple(1), "and", t_cherry(15)

This is perhaps a little clearer than the following:

class tag_object(object):
    def __init__(self, singular, plural):
        self.singular = singular
        self.plural = plural

    def tag(self, n):
        if n == 1:
            return "1 " + self.singular
        else:
            return str(n) + " " + self.plural

t_apple = tag_object("apple", "apples")
t_cherry = tag_object("cherry", "cherries");
print t_apple.tag(1), "and", t_cherry.tag(15)

As a rule of thumb: If the thing is really only a single function, and it is only capturing static state, then consider a closure. If the thing is intended to have mutable state, and/or has more than one function, use a class.

Another way to put it: If you are creating a dict of closures, you are essentially duplicating the class machinery by hand. Better to leave it to the language construct designed to do it.

like image 97
MtnViewMark Avatar answered Sep 20 '22 03:09

MtnViewMark