views:

60

answers:

2

Beginner in JS :) needs an explanation of code piece from Crockford's book, section 4.15:

var memoizer = function (memo, fundamental) {
    var shell = function (n) {
        var result = memo[n];
        if (typeof result !== 'number') {
            result = fundamental(shell, n);
            memo[n] = result;
        }
        return result;
    };
    return shell;
};

var fibonacci = memoizer([0, 1], function (shell, n) {
    return shell(n - 1) + shell(n - 2);
});

Question: How do we calculate fibonacci(15), and if it is simple fibonacci(15) call, then how it works in detail?

Thanks for help.

A: 

To evaluate the function, you simply need to call it:

fibonacci(15);

If you want to see the result, the simplest way would be:

alert(fibonacci(15));

If you want to do this more often, then download Firebug, and do this at the bottom of your script:

Console.log(fibonacci(15));

Or type this directly into the Firebug console, and then press return:

fibonacci(15)
Douglas
Max
Pretty sure he's looking for somebody to walk him through how the code works, using `15` as sample input
meagar
To see how it works in absolute detail, you could again download Firebug, then step through a call to fibonacci(15) using the debugger. Look for the Step Into button. You could add a watch expression "n" to show you what the value of n is as it changes.
Douglas
A: 

As the comments to your question suggest, you should walk through the code in a debugger to get a good understanding of what's going if you can't follow the explanation in the book. But I'll give you a brief overview of what's happening:

What's being demonstrated is 'memoisation' which is a common optimisation technique used in functional programming. A function is said to be pure if the result depends only on the arguments passed into it. So, if a function is pure you can cache the result based on the arguments - this technique is called memoisation. You would do this if a function is expensive to calculate and is called multiple times.

The classical example used to demonstrate this (as here) is generating Fibonacci numbers. I'm not going to go through how those are worked out, but basically as you go to higher and higher numbers you repeat yourself more and more as each number is calculated from the preceeding two numbers. By memoising each intermediate result you only have to calculate them once hence making the algorithm much faster (much, much faster as you go higher up the sequence).

As far as this code is concerned the memoizer takes two parameters - 'memo' which is the cache. In this case it's going in with the first two values already filled in the '[0,1]' - these are the first two Fibonacci numbers.

The second parameter is the function to which the memoisation will be applied. In this case a recursive Fibonacci function:

function (shell, n) { return shell(n - 1) + shell(n - 2); }

i.e. the result is the sum of the previous two numbers in the sequence.

The memoizer first of checks to see if it already has a cached result. If it does it returns that immediately. If not it calculates the result and stores it in the cache. Without doing this it'd be repeating itself again and again and rapidly gets impossibly slow once to get to the higher numbers in the sequence.

FinnNk
@FinnNk: thanks for your answer. However my vague part was different, but I got it already by myself :)... I was wondering how `15` gets passed into body of `memoizer` function when `fibonacii(15)` is called. The answer is trivial :) : `memoizer` returns a `function(n)` (`shell` variable), so var `fibonacci` which is assigned a `function(n)` returned by `memoizer` accepts `n=15`.
Max