2

I was reading Professor Frisby's Mostly adequate guide to functional programming and I came across this code example shown below. I don't understand why cache is not reset to {} each time squareNumber is called.

var memoize = function(f){
    var cache = {}; // why is this not reset each time squareNumber is called?

    return function() {
        var arg_str = JSON.stringify(arguments);
        cache[arg_str] = cache[arg_str]|| f.apply(f, arguments);
        return cache[arg_str];
    };
}

var squareNumber = memoize(function(x){ return x*x; });
squareNumber(4);
//=> 16
squareNumber(4); // returns cache for input 4
//=> 16
squareNumber(5);
//=> 25
squareNumber(5); // returns cache for input 5
//=> 25

One theory I have is that since memoize is a global variable the cache variable is not reset every time it is called. But I can't seem to find a good solution.

Mark Kuczmarski
  • 173
  • 3
  • 16
  • 1
    Why do you think it *would* be reset? The function that `memoize` returns doesn't ever change the value of `cache`, so what would change it? – Pointy Sep 15 '15 at 00:02

2 Answers2

5

Because the function memoize is only being called once. memoize(function(x){ return x*x; }) simply gives the return value, which happens to be a function.

Spencer Wieczorek
  • 21,229
  • 7
  • 44
  • 54
2

When you execute:

var squareNumber = memoize(function(x){ return x*x; });

The cache variable inside of memoize() is initialized and a reference to the inner function is returned and assigned to squareNumber. That inner function has a reference to that cache object and each time it is called when you do squareNumber(x), that inner function continues to have a reference to that same original cache variable.

This is actually the intended behavior of this design pattern so the cache can persist from one call to the next.

If you want a fresh copy of the cache, then you must call memoize() again to start over with a fresh cache and fresh inner function that has a reference to the new cache variable.

FYI, this is called a closure because though memoize() has run and completed, the reference to the inner function that was returned from executing memoize() has references to the local variables of memoize() so those local variables are not garbage collected by the JS interpreter, even though memoize() has long since finished executing. This is called a closure.

jfriend00
  • 683,504
  • 96
  • 985
  • 979