5

I am reading the book "Eloquent JavaScript".

In Chapter 5 he describes a particular higher-order function. It is called noisy() it is printed below...

function noisy(f) {
  return (...args) => {
   console.log("calling with", args);
   let result = f(...args);
   console.log("called with", args, ", returned", result);
   return result;
 };
}

Here is the part that is confusing me. He calls the function noisy as follows...

noisy(Math.min)(3,2,1);

I do not understand why the function is called that way. Why isn't it called like this...

noisy(Math.Min(3,2,1))

Edit: I see now what is going on. It was explained by Simone below.

noisy(Math.min)(3,2,1) is equivalent to (noisy(Math.min))(3,2,1).
3
  • noisy accepts a function and returns a function which calls the passed function. Commented Apr 24, 2018 at 14:12
  • I assume the purpose of noisy is to make some (well...) noise upon invoking the function (f) that is being passed to it. So, after you call noisy(Math.min) you get back a function that is then invoked using the (3,2,1) parameters. Essentially, decorating (or "proxying") the call to f for the purpose of logging to console before and after the actual invocation of f. Commented Apr 24, 2018 at 14:12
  • 1
    Possible duplicate of What is 'Currying'? Commented Apr 24, 2018 at 14:13

3 Answers 3

2

If you try to get the type of noisy, you'll get:

typeof noisy
>> "function"

Same thing if you ask for the type of noisy(Math.min):

typeof noisy(Math.min)
>> "function"

If you want you can also store this function into a variable:

const noisyFunction = noisy(Math.min)

So that you can call it like a regular function:

noisyFunction(1,2,3)

noisy(Math.min)(3,2,1) is exactly the same, just written in a different, shorter way. The main point is, a higher-order function is just a function that returns a function.

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

4 Comments

Ok I get it. It could have been written like this (noisy(Math.min))(3,2,1) The precedence of the () operator causes it to be executed like I have written?
Yes, correct, but it won't work if written like in your second example, because they're not equivalent. noisy(Math.min(3,2,1)) is a regular function call where Math.min(3,2,1) is the first and only argument.
Yes I understand that now. Thanks.
Thanks so much for posting this. I had the exact same question!
0

noisy returns a function that uses the parameter f as a callback function.

Here is an es5 version of the code (which needs a little more code to maintain functionality) to help you understand:

function noisy(f) {
    return function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        console.log("calling with", args);
        var result = f.apply(void 0, args);
        console.log("called with", args, ", returned", result);
        return result;
    };
}
//test
console.log(noisy(Math.min)(3, 2, 1));

Comments

0

noisy(Math.min) returns a function (see the return statement: return (...args) => { ... }).

noisy(Math.min)(3,2,1); just immediately calls that function.

You could also first assign the function to a variable and then call it like this:

let fnct = noisy(Math.min);
fnct(3,2,1);

You cannot call it like noisy(Math.Min(3,2,1)) as Math.min(3,2,1) returns a number but noisy expects a function reference to be passed (hence Math.min - note its missing the () as it's passing a reference to that function rather than the result of its execution).

Your call would break in line 4, i.e:

let result = f(...args);

as f is not a function in your case but rather the result of Math.min(3,2,1) // = 1 .

Comments

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.