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;
}
1

1 Answer 1

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?)

Sign up to request clarification or add additional context in comments.

2 Comments

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?
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).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.