Play Home Contribute Github Join Us! Discourse Staff Members Github Contribution Guides Team

What's going on with Python closures?

#1

I started playing CodeCombat yesterday and noticed some bizarre behavior when attempting to use closures in Python. For example, consider the following code:

def makeAdder(n):
    def adder(m):
        return m + n
    return adder

f = makeAdder(4)
self.say(f(3))

I would expect f to be a function which adds 4 to its argument, but self.saying f(3) produces [object Object] instead of 7. You can check with self.say(f) that f does get assigned some kind of function, and the object produced by f(3) appears to have .next and .throw methods. What’s going on here?

Strange behavior for Python code that uses first-class functions
#3

I tested the code above and it works. So decided to write it in java-script.

///////////// version 1 //////////////////
var makeAdder = (function(n){
    function adder (m){
        return m + n;
    } 
    return adder;
})(4);
console.log(makeAdder(3));
///////////// version 2 //////////////////
var makeAdder = function(n){
    function adder (m){
        return m + n;
    } 
    return adder;
};
var f = makeAdder(4);
console.log(f(3));
///////////// version 3 //////////////////
var makeAdder = function(n){
    function adder (m){
        return m + n;
    } 
    return {adder};
};
var newMakeAdder = new makeAdder(4);
console.log(newMakeAdder.adder(3));

Versions 1&2 are working.


Version 3 fails in CoCo but works in pythontutor.

Why? Is object creation in CoCo allowed and how?

#4

this was 3 years ago…

#5

For interested in java-script objects and closures - found the solution accidentally just now:

var makeAdder = (function(n){
    return{
      adder : function(m){
        return m + n;
      }  
    }; 
})(4);    
var f = makeAdder.adder(3);
hero.say('makeAdder.adder(3) returns ' + f);

image
Curious if there are other ways of doing it?

#6

As long as the new post is relevant, it doesn’t matter how old it is.