2

The code is from Eloquent Functional Programming. I have trouble understanding the test(element). If the test(element) is referencing equals(x), then is element = 0 since there is only one parameter?

function count(test, array) {
    return reduce(function(total, element) {
        return total + (test(element) ? 1 : 0); 
    }, 0, array);
}

function equals(x) {
    return function(element) {return x === element;}; // element gets value from x?
}

function countZeroes(array) {
    return count(equals(0), array);
}

Previous code

function forEach(array, action) {
    for (var i = 0; i < array.length; i++)
        action(array[i]);
}

function reduce(counter, base, array) {
    var total = 0;
    forEach(array, function (element) {
        total += counter(element);
    });
    return total;
}
Palec
  • 12,743
  • 8
  • 69
  • 138
  • possible duplicate of [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – p.s.w.g Feb 09 '14 at 00:20

1 Answers1

1

element does not get its value from x.

Rather, element refers to a parameter which will have it's value supplied when the function is invoked - by count in this case. The variable x, a parameter in the outer scope, is bound in scope of the function/closure that is returned when equals is invoked. That is, equals(0) evaluates to a function/closure which is then used as a predicate to count.

First, let's use equals directly, bearing in mind that equals evaluates to a function as does equals(0):

   equals(0)(1) // -> false, x=0, element=1
   equals(0)(0) // -> true,  x=0, element=0
// ^^^^^^^^^    - invokes equals(..), evaluates to the closure binding `x`
//          ^^^ - invokes the previously returned closure, supplying `element`

But because that's a bit hard to abstractly see, let's give the closure a name:

var equalToZero = equals(0)  // -> function, x=0
//                ^^^^^^^^^ - invokes equals(..), evaluates to the closure binding `x`
   equalToZero(1)            // -> false, x=0, element=1
   equalToZero(0)            // -> true,  x=0, element=0
// ^^^^^^^^^^^^^^ - invokes the previously returned closure, supplying `element`

// And just as before, it is the `count` function that
// supplies the `element` argument when it invokes the function.
// (The function is locally known by the name `equalToZero`.)
count(equalToZero, array);

Which we could imagine was written like this:

function equalToZero (element) {
    return 0 === element;
}

The difference being, of course, that in the above function the value (0) is hard-coded, while in the closure-creating equals it is whatever the bound x variable evaluates to.

(For more wonderful goodness on closures, see How do JavaScript closures work?)

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
  • Thanks for explaining. I am new to Javascript and what I know is closure needs to create a variable, like you did "var equalToZero = equals(0)", but I don't see that in the code. Then how does closure works without it? – user3263884 Feb 09 '14 at 00:46
  • Functions are *just* values. You can either use the function *returned* from `equals(0)` directly as in the first block or, as in the second block, store the function for use later. It is *still* a closure/function in either case - that does not change. Maybe consider that `equals(0)(1)` is *equivalent* to `(equals(0))(1)` - that is, `equals` is invoked *first* (when the closure bound to `x` is *returned*) and then the resulting function, be it used directly or assigned to `equalToZero`, is invoked *later* (with an argument supplied for `element`). – user2864740 Feb 09 '14 at 00:49