Higher-order functions in Javascript - javascript

I am reading Eloquent JavaScript (The new edition) and I reached the part on higher order functions and I'm confused on what's happening in the following code.
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false
Why is the call to the function noisy like this? Is (Boolean) a cast? A cast for what? the return value? or the argument? why not (Boolean)noisy(0) if its the return value. Or noisy((Boolean) 0) if the argument is the one being casted.
noisy(Boolean)(0)
What is happening in this line? Where is f() even defined?
var val = f(arg);

Boolean is a function. It's the function you're calling indirectly through noisy. A bit confusing, I know, because it looks like the name of a type. But in JavaScript, those initially-capped things (Boolean, Number, String, and so on) are functions. When you call Boolean (without using new), it tries to convert the argument you gave it into a boolean primitive value and returns the result. (See §15.6.1 in the spec.)
f is the name of the argument in the noisy function.
Functions in JavaScript are first-class objects. You can pass them into other functions as arguments just like any other object.
When you do
noisy(Boolean)(0)
There are two things going on. First:
// (In effect, we're not really creating a variable...)
var x = noisy(Boolean);
That gives us a function that, when called, will call Boolean with the argument we give it while also doing those console.log statements. This is the function you see being created in noisy (return function(arg)...);
Then we call that function:
x(0);
And that's when you see the console output. Since Boolean(0) is false, you see Boolean return that value.
Here's a much simpler example:
function foo(bar) {
bar();
}
function testing() {
alert("testing got called");
}
foo(testing);
There, I'm passing the function testing into foo. The argument name I'm using for that within foo is bar. The line bar(); calls the function.

A function without the () is the actual function. A function with () is an invocation of the function. Also keep in mind that JavaScript is a loosely typed language, so you don't declare variable types. I've added some comments to your example to try and help.
// We define a function named noisy that takes in an argument named f. We are expecting f to be a function but this isn't enforced till the interpreter throws an error.
function noisy(f) {
// Noisy returns a single item, an anonymous function. That anonymous function takes in an argument named arg
return function(arg) {
console.log("calling with", arg);
// Our anonymous function then takes f (It can use f because its defined inside noisy, see closures for more details) and invokes it with the argument arg and stores the result in a variable named val.
var val = f(arg);
console.log("called with", arg, "- got", val);
// It now returns val
return val;
};
}
So then noisy(Boolean)(0) works like this
f is the function Boolean
noisy returns a function like this
function(arg) {
var val = Boolean(arg);
return val;
}
So now we have
our returned function(0)
which executes like normal to become
function(0) {
var val = Boolean(0); // false
return val;
}

I'm relatively new to JS and I've also just been reading through Eloquent Javascript and I found it easier to understand once I understood the calling of the function (answering your point 1):
noisy(Boolean)(0);
The noisy(Boolean) creates a new function and the (0) is after it because it is being passed as an argument into that new function. If you refer back to the greater than example:
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
It could also be called in this way:
greaterThan(10)(11);
I hope that clarifies your first question about why it was called that way.
For the second question. The f in:
var val = f(arg);
is the Boolean function that was passed into noisy when noisy(Boolean) was entered. It was then used as the argument in the noisy function. I also didn't realise that Boolean could be a function in itself and not just a data type. As others have said - it converts the argument you gave it into a Boolean value and returns the result.
Therefore val becomes Boolean(arg) which becomes Boolean(0) which evaluates to false. If you try call noisy(Boolean)(1);you will see it return true. The console.log("called with", arg, "- got", val); simply logs the argument (0 in this case) and the result of evaluating it (false).
In effect, it has changed the Boolean function into one that logs the argument and result, as well as returning the result.
I hope this helps. Just writing it has helped my own understanding.

Javascript variables do not have a static datatype. They can be assigned variables of different datatypes also.
There is no concept of typecasting in JS like in JAVA etc.
() in a function call corresponds to the invoking of the function.
Here, Boolean seems to be a higher order function which is passed as a parameter to the noisy function. The result of the noisy function will be
function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
The second parantheses with 0 is used to invoke this result.
Here, within the above function, note the below line.
var val = f(arg);
Here, f corresponds to the Boolean function which was passed earlier. arg corresponds to 0.
Since val is returned, the result of the expression will be the result of Booelan(0).

In case you're still having trouble with this, here's how I understand it (it gave me a headache too..)
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0)
A function is just a regular value. The previous sentence is key to understanding what's going on here.
Our noisy(f) function is a value. It is what it returns.
noisy(f) returns a function which takes an argument (arg).
noisy(f) also takes an argument (f). Inner functions (functions called from within functions) have access to variables and arguments which were passed to the outer function.
We're calling our outer function and passing it the argument Boolean. Our outer function returns its inner function which takes an argument (0).
By understanding the above it should become clear that noisy(Boolean(0)) would simply pass an argument to our outer function,
while not passing anything to the inner function which is returned by our outer function.
It's so simple really. Now that we understand it, it's hard to believe it gave us such a headache to begin with... */`

Related

What Javascript Syntax is This format function()()? [duplicate]

I am reading Eloquent JavaScript (The new edition) and I reached the part on higher order functions and I'm confused on what's happening in the following code.
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false
Why is the call to the function noisy like this? Is (Boolean) a cast? A cast for what? the return value? or the argument? why not (Boolean)noisy(0) if its the return value. Or noisy((Boolean) 0) if the argument is the one being casted.
noisy(Boolean)(0)
What is happening in this line? Where is f() even defined?
var val = f(arg);
Boolean is a function. It's the function you're calling indirectly through noisy. A bit confusing, I know, because it looks like the name of a type. But in JavaScript, those initially-capped things (Boolean, Number, String, and so on) are functions. When you call Boolean (without using new), it tries to convert the argument you gave it into a boolean primitive value and returns the result. (See §15.6.1 in the spec.)
f is the name of the argument in the noisy function.
Functions in JavaScript are first-class objects. You can pass them into other functions as arguments just like any other object.
When you do
noisy(Boolean)(0)
There are two things going on. First:
// (In effect, we're not really creating a variable...)
var x = noisy(Boolean);
That gives us a function that, when called, will call Boolean with the argument we give it while also doing those console.log statements. This is the function you see being created in noisy (return function(arg)...);
Then we call that function:
x(0);
And that's when you see the console output. Since Boolean(0) is false, you see Boolean return that value.
Here's a much simpler example:
function foo(bar) {
bar();
}
function testing() {
alert("testing got called");
}
foo(testing);
There, I'm passing the function testing into foo. The argument name I'm using for that within foo is bar. The line bar(); calls the function.
A function without the () is the actual function. A function with () is an invocation of the function. Also keep in mind that JavaScript is a loosely typed language, so you don't declare variable types. I've added some comments to your example to try and help.
// We define a function named noisy that takes in an argument named f. We are expecting f to be a function but this isn't enforced till the interpreter throws an error.
function noisy(f) {
// Noisy returns a single item, an anonymous function. That anonymous function takes in an argument named arg
return function(arg) {
console.log("calling with", arg);
// Our anonymous function then takes f (It can use f because its defined inside noisy, see closures for more details) and invokes it with the argument arg and stores the result in a variable named val.
var val = f(arg);
console.log("called with", arg, "- got", val);
// It now returns val
return val;
};
}
So then noisy(Boolean)(0) works like this
f is the function Boolean
noisy returns a function like this
function(arg) {
var val = Boolean(arg);
return val;
}
So now we have
our returned function(0)
which executes like normal to become
function(0) {
var val = Boolean(0); // false
return val;
}
I'm relatively new to JS and I've also just been reading through Eloquent Javascript and I found it easier to understand once I understood the calling of the function (answering your point 1):
noisy(Boolean)(0);
The noisy(Boolean) creates a new function and the (0) is after it because it is being passed as an argument into that new function. If you refer back to the greater than example:
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
It could also be called in this way:
greaterThan(10)(11);
I hope that clarifies your first question about why it was called that way.
For the second question. The f in:
var val = f(arg);
is the Boolean function that was passed into noisy when noisy(Boolean) was entered. It was then used as the argument in the noisy function. I also didn't realise that Boolean could be a function in itself and not just a data type. As others have said - it converts the argument you gave it into a Boolean value and returns the result.
Therefore val becomes Boolean(arg) which becomes Boolean(0) which evaluates to false. If you try call noisy(Boolean)(1);you will see it return true. The console.log("called with", arg, "- got", val); simply logs the argument (0 in this case) and the result of evaluating it (false).
In effect, it has changed the Boolean function into one that logs the argument and result, as well as returning the result.
I hope this helps. Just writing it has helped my own understanding.
Javascript variables do not have a static datatype. They can be assigned variables of different datatypes also.
There is no concept of typecasting in JS like in JAVA etc.
() in a function call corresponds to the invoking of the function.
Here, Boolean seems to be a higher order function which is passed as a parameter to the noisy function. The result of the noisy function will be
function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
The second parantheses with 0 is used to invoke this result.
Here, within the above function, note the below line.
var val = f(arg);
Here, f corresponds to the Boolean function which was passed earlier. arg corresponds to 0.
Since val is returned, the result of the expression will be the result of Booelan(0).
In case you're still having trouble with this, here's how I understand it (it gave me a headache too..)
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0)
A function is just a regular value. The previous sentence is key to understanding what's going on here.
Our noisy(f) function is a value. It is what it returns.
noisy(f) returns a function which takes an argument (arg).
noisy(f) also takes an argument (f). Inner functions (functions called from within functions) have access to variables and arguments which were passed to the outer function.
We're calling our outer function and passing it the argument Boolean. Our outer function returns its inner function which takes an argument (0).
By understanding the above it should become clear that noisy(Boolean(0)) would simply pass an argument to our outer function,
while not passing anything to the inner function which is returned by our outer function.
It's so simple really. Now that we understand it, it's hard to believe it gave us such a headache to begin with... */`

Js currying with condition

im trying to understand this code for long time i know currying function but confused with this code please explain theory behind
var currying = function(fn) {
var args = [];
return function() {
if (!!arguments.length){
[].push.apply(args, arguments);
return arguments.callee;
} else {
// what is 'this' in apply method
return fn.apply(this, args);
}
}
}
// currying var or args
// please explain the code below
var find = function(arr, el){
return arr.indexOf(el) !== -1;
}
var newFind = currying(find)([1,2,3]);
console.log( newFind(1)());
console.log( newFind(2)());
To make it easier to explain, let's convert the last part of the code:
// newFind = currying(find)([1,2,3]);
// console.log(newFind(1)());
// above is the same with below
console.log( currying(find)([1,2,3])(1)());
currying takes a function find so fn in currying is find.
As it return a function, it can be called as it's shown on the code currying(find)([1,2,3])
let's look at this part, currying(find)([1,2,3]).
It executes the returned method of currying. It can access the arguments with keyword arguments that is the array of [1,2,3] on the code.
The argument is the array which means it has the length value. Then the arguments is pushed into args array and return its callee which means inner method of currying.
As it returns method again, it can be called again with next paramter (1) of currying(find)([1,2,3])(1)().
Again, it executes the inner method of currying with arguments: 1. Then it is not an array so, it calls fn.apply(this, args).
this keyword in the code means nothing in this case. you can replace this to null or you can use fn(...args) instead. the code is for converting array of argumnts to each argument. e.g. [[1,2,3], 1] is converted to [1,2,3], 1
Then, finally it executes find function with parameter [1,2,3], 1. You should remember all this thing is from returned method of currying so, you must call it as a function. append () at the end to execute the function.

How does javascript handle `this` when doing property lookups?

I'm writing a function that needs to take an object and call a method on that object. I'm having trouble wrapping my head around how this is set when invoking a function.
Let's say I have this object:
myObj = {
x: 2,
get: function() {
return this.x;
}
};
If I simply do:
callbackEval = function(fn) {
return fn();
};
and then invoke it as
callbackEval(myObj.get)
This returns undefined, since this isn't bound. Obviously if I write this as
callbackEval(function() {
return myObj.get()
});
then it returns 2, as I'd expect.
But if, instead of passing a callback, I pass a property name, look up that property, and then call that function, I get mixed results.
Let's say I write these variants:
propEval = function(obj, fnName) {
const fn = obj[fnName];
return fn();
}
propEval2 = function(obj, fnName) {
return obj[fnName]();
}
propEval3 = function(obj, fnName) {
return (obj[fnName])()
}
propEval4 = function(obj, fnName) {
return (obj[fnName] || true)()
}
and call them like so:
propEval(myObj, "get");
propEval2(myObj, "get");
propEval3(myObj, "get");
propEval4(myObj, "get");
then, in order, I get:
undefined
2
2
undefined
What's the difference between how the javascript handles these 4 variations? Why is this bound when we make the calls in propEval2 and propEval3, but not in propEval4?
The partial answer: this is, bluntly put, a function's argument. It's 0-th argument, hidden and passed to it in a special way (or in explicit way - with call and apply). There's also no methods, BTW, just functions that happen to be properties of an object. If you invoke a function this way: foo.bar() (=== foo['bar']()), you implicitly pass to it foo as its this binding. When you invoke it this way: bar(), you do not.
Hence: propEval - no object, no this binding.
propEval2 - the classic example of invoking a so-called "method".
propEval3 - the () are irrelevant here. With or without them, the expression is evaluated the same, with the member access operator and the function call operator having the same precedence.
propEval4 - it looks like the one above, doesn't it? Hah! What it actually does is first, evaluate the expression (obj[fnName] || true), then invokes the result. It might as well be
const someTemporaryVariable = obj[fnName] || true;
return someTemporaryVariable();
I think.
propEval1 when you call function myObj.get, myObj is being passed in as the 'this' context. When you call fn you're calling the function without a context thus using the enclosing context. Note context being supplied is determined by where the function is being called and whether theres a . or not.
propEval2 and propEval3 are the same (parens don't matter) since you're always calling the function as a property of myObj. myObj.get is the same as myObj['get'].
propEval4 I haven't seen this one but it seems that with the || it evaluates the condition and then executes the return of the condition which will be a reference to the function resulting in something similar to propEval1.

Eloquent JavaScript Chapter 5 Higher-Order Functions - function that changes other functions example [duplicate]

I am reading Eloquent JavaScript (The new edition) and I reached the part on higher order functions and I'm confused on what's happening in the following code.
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false
Why is the call to the function noisy like this? Is (Boolean) a cast? A cast for what? the return value? or the argument? why not (Boolean)noisy(0) if its the return value. Or noisy((Boolean) 0) if the argument is the one being casted.
noisy(Boolean)(0)
What is happening in this line? Where is f() even defined?
var val = f(arg);
Boolean is a function. It's the function you're calling indirectly through noisy. A bit confusing, I know, because it looks like the name of a type. But in JavaScript, those initially-capped things (Boolean, Number, String, and so on) are functions. When you call Boolean (without using new), it tries to convert the argument you gave it into a boolean primitive value and returns the result. (See §15.6.1 in the spec.)
f is the name of the argument in the noisy function.
Functions in JavaScript are first-class objects. You can pass them into other functions as arguments just like any other object.
When you do
noisy(Boolean)(0)
There are two things going on. First:
// (In effect, we're not really creating a variable...)
var x = noisy(Boolean);
That gives us a function that, when called, will call Boolean with the argument we give it while also doing those console.log statements. This is the function you see being created in noisy (return function(arg)...);
Then we call that function:
x(0);
And that's when you see the console output. Since Boolean(0) is false, you see Boolean return that value.
Here's a much simpler example:
function foo(bar) {
bar();
}
function testing() {
alert("testing got called");
}
foo(testing);
There, I'm passing the function testing into foo. The argument name I'm using for that within foo is bar. The line bar(); calls the function.
A function without the () is the actual function. A function with () is an invocation of the function. Also keep in mind that JavaScript is a loosely typed language, so you don't declare variable types. I've added some comments to your example to try and help.
// We define a function named noisy that takes in an argument named f. We are expecting f to be a function but this isn't enforced till the interpreter throws an error.
function noisy(f) {
// Noisy returns a single item, an anonymous function. That anonymous function takes in an argument named arg
return function(arg) {
console.log("calling with", arg);
// Our anonymous function then takes f (It can use f because its defined inside noisy, see closures for more details) and invokes it with the argument arg and stores the result in a variable named val.
var val = f(arg);
console.log("called with", arg, "- got", val);
// It now returns val
return val;
};
}
So then noisy(Boolean)(0) works like this
f is the function Boolean
noisy returns a function like this
function(arg) {
var val = Boolean(arg);
return val;
}
So now we have
our returned function(0)
which executes like normal to become
function(0) {
var val = Boolean(0); // false
return val;
}
I'm relatively new to JS and I've also just been reading through Eloquent Javascript and I found it easier to understand once I understood the calling of the function (answering your point 1):
noisy(Boolean)(0);
The noisy(Boolean) creates a new function and the (0) is after it because it is being passed as an argument into that new function. If you refer back to the greater than example:
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
It could also be called in this way:
greaterThan(10)(11);
I hope that clarifies your first question about why it was called that way.
For the second question. The f in:
var val = f(arg);
is the Boolean function that was passed into noisy when noisy(Boolean) was entered. It was then used as the argument in the noisy function. I also didn't realise that Boolean could be a function in itself and not just a data type. As others have said - it converts the argument you gave it into a Boolean value and returns the result.
Therefore val becomes Boolean(arg) which becomes Boolean(0) which evaluates to false. If you try call noisy(Boolean)(1);you will see it return true. The console.log("called with", arg, "- got", val); simply logs the argument (0 in this case) and the result of evaluating it (false).
In effect, it has changed the Boolean function into one that logs the argument and result, as well as returning the result.
I hope this helps. Just writing it has helped my own understanding.
Javascript variables do not have a static datatype. They can be assigned variables of different datatypes also.
There is no concept of typecasting in JS like in JAVA etc.
() in a function call corresponds to the invoking of the function.
Here, Boolean seems to be a higher order function which is passed as a parameter to the noisy function. The result of the noisy function will be
function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
The second parantheses with 0 is used to invoke this result.
Here, within the above function, note the below line.
var val = f(arg);
Here, f corresponds to the Boolean function which was passed earlier. arg corresponds to 0.
Since val is returned, the result of the expression will be the result of Booelan(0).
In case you're still having trouble with this, here's how I understand it (it gave me a headache too..)
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(0)
A function is just a regular value. The previous sentence is key to understanding what's going on here.
Our noisy(f) function is a value. It is what it returns.
noisy(f) returns a function which takes an argument (arg).
noisy(f) also takes an argument (f). Inner functions (functions called from within functions) have access to variables and arguments which were passed to the outer function.
We're calling our outer function and passing it the argument Boolean. Our outer function returns its inner function which takes an argument (0).
By understanding the above it should become clear that noisy(Boolean(0)) would simply pass an argument to our outer function,
while not passing anything to the inner function which is returned by our outer function.
It's so simple really. Now that we understand it, it's hard to believe it gave us such a headache to begin with... */`

Callbacks and Higher Order functions Javascript

This is a problem from chapter 5 of Eloquent JS http://eloquentjavascript.net/05_higher_order.html
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
noisy(Boolean)(12);
// → calling with 0
// → called with 0 - got false
Can someone please explain how f(arg) makes sense? I mean he is calling the argument f on another argument arg?? I am very confused.
How about the part that has return val; Why does that have to be there? When I delete it, the code still runs like it should.
Lastly, can some explain the code interpretation line by line? How does passing boolean make sense in the example?
Thank you so much
One simple rule to remember is that nested functions in Javascript (e.g. functions declared within other functions) have access to all the variables and arguments of their parent functions.
When noisy(f) is called and it returns another function, that creates a closure in Javascript. That means that even though noisy(f) has finished execution, it's arguments and any local variables are still alive and can still be used by the inner function.
So, when that inner function is then called, it has full access to the f argument from the prior execution of its parent function. Here's an MDN reference on closures which might be worth reading and a StackOverflow answer explaining closures.
So, let's break down what your code is doing step by step:
function noisy(f) {
return function(arg) {
console.log("calling with", arg);
var val = f(arg);
console.log("called with", arg, "- got", val);
return val;
};
}
// split up noisy(Boolean)(12); into two steps
var temp = noisy(Boolean);
temp(12);
When noisy(Boolean) is called, that returns the inner function and for any future invocation of that inner function, the f argument is set to the Boolean constructor function.
When that returned function is then called with it's own argument as in temp(12) above, then it ends up executing Boolean(12) and returning that (who's value will be true).
Working demo: http://jsfiddle.net/jfriend00/mkn839gu/
Basics:
noisy maps a function to another function that does the same as the original but writes input and output value ( moreprecisely their string representations) to the console.
Q1: The intention seems to be the enhancement of object constructors with a simple logging facility to show which initialization arguments produce which kind of object state. To this end, noisy returns a function object - the original function enhanced by output to the console.
Q2: The enhanced Boolean constructor is called without assigning its return value. Thus it makes no difference to the code whether the enhanced constructor does return a value or not.
Q3: Boolean reveals what boolean values you get for different initialization arguments. I guess the lesson to be learned is that a numerical of 0 gets you a false, anything else true (the latter is informed guessing on my part, but with noisy you have a tool to generically check that for arbitrary constructors and initialization values).
keeping it simple:
the argument in function noisy (that acts as a wrapper) is actually just
(Boolean());
(for ref on boolean-type check this).
Furthermore you use 0 as argument of console.log in the inner function,
and as the argument of Boolean() (in var val).
How about the part that has return val; Why does that have to be there? When I delete it, the code still runs like it should.
as long as you're using console.log you're not actually using the return statement, but if you were to do this
console.log(noisy(Boolean)(0))
you can see the return statement after the previous console.logs

Categories