What's going on with Python closures?

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?

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?

this was 3 years ago…

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?

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