How does this function modify the other? (Higher Order Functions) - javascript

What is this code doing? How is it executing? What is x equal to?
Another useful type of higher-order function modifies the function value it is given:
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));

The function negate() returns a Function object that, when called, will return !func(x); for whatever argument x is passed. This Function object is being stored in the variable isNotNaN with func bound to the built-in function isNaN(). In the next line the function object stored in isNotNaN is being called with the argument NaN (a JavaScript keyword). It is at this point that x becomes bound to NaN. The return value is passed to the function show() (which isn't shown here).
For more info, read up on JavaScript functions here and consult the docs for JavaScript's Function object and function expression.
EDIT: Why do this? Sometimes it's useful to have a function that inverts a given boolean function. For instance, suppose you have some complex predicate and you want to filter an array for all elements for which the predicate is false. You can use negate() to turn the predicate function into a function that evaluates to true for those elements and just use Array.prototype.filter() to do the job. Think of it as a utility function that saves you having to write a lot of function(x) { return !predicate(x); } every time you want the inverse of a boolean-valued function. It's kind of trivial, but a lot of JS libraries (e.g., underscore.js, jquery, etc.) have a boatload of utility functions like this.
P.S. I would have written it more generally:
function negate(func) {
return function() {
return !func.apply(null, arguments);
};
}
That way, it can be used with boolean-valued functions of an arbitrary number of arguments.

Related

Eloquent Javascript: Higher Order Functions

I'm going through Eloquent Javascript: Higher Order Functions example below and already read questions and answers here and here. But I'm still very confused.
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
How can (0) be passed into noisy(f) since noisy() only takes one parameter and that is (Boolean)? I can see the inner function f(arg) is basically Boolean(0), but I don't understand how two parameters can get passed into a function that only allow one parameter. Would "noisy(Boolean)(0)(1)(2)(3);" be a valid function call? If so, how would you differentiate each value after Boolean within the noisy function? Which value will be referenced by "arg"?
The book noted the example function is modifying another function. Which function is being modified? I'm not understanding what the author meant by "modified".
but I don't understand how two parameters can get passed into a
function that only allow one parameter
noisy returns a function, Boolean is passed to noisy, 0 is passed to anonymous function returned from noisy, where f is Boolean, val becomes Boolean(0).
For example
function fn1(arg1) {
return function fn2(arg2) {
console.log(arg1, arg2)
}
}
// Call fn1, inside fn1 fn2 is called with `"b"` as parameter.
fn1("a")("b") // `a b`, `fn2`
This is the concept of currying in JavaScript where you can curry functions to return partially applied functions or pass in other functions
How can (0) be passed into noisy(f) since noisy() only takes one parameter and that is (Boolean)?
The answer to this is the curried function noisy() which expects a function f as parameter and returns another function. The returned function has a closure over noisy and as a result it can identify that Boolean was passed as parameter to noisy even after it was returned. That's why calling noisy(Boolean)(0) basically substitutes f=Boolean, arg=0
Refer this for more on currying: http://javascript.crockford.com/www_svendtofte_com/code/curried_javascript/ and closures: https://developer.mozilla.org/en/docs/Web/JavaScript/Closures

Passing arguments to filter()

I have a function that takes an array and then a number of arguments. In that function I want to use the filter() method on the array, but I want to use arguments[i]. As an example:
function destroyer(arr) {
var test = arr.filter(function(value){
return value != arguments[1];
});
return test;
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
Calling arguments[1] there doesn't give me what I want, because I'm guessing the anonymous function has its own arguments that filter() is using. One solution I thought of was creating an array and copying the arguments to that. But I was wondering if there was a way to pass the arguments to filter? I know filter has a thisArg value, but I'm not sure how to use that to get what I want.
Edit: I have tried googling for a solution, and most of the solutions involve using bind or apply. However, I couldn't find anything directly related to filter() or similar methods like forEach, reduce, map, etc. I've tried using "this" as the thisArg value, but that doesn't seem to do anything. I've tried using bind and apply with it, but I can't seem to get the correct syntax for it.
If you have access to an ES6 environment, you can use "spread parameters" (...) to represent your variable-length argument list. Along with arrow functions, and Array#includes, your code could be quite compact:
function destroyer(arr, ...destroy) {
return arr.filter(value => !destroy.includes(value));
}
I have a working solution (with copying the arguments to an array), but I'm more interested in trying to figure how to pass the arguments to filter() to better understand how filter() and other similar methods work.
You don't need to pass the arguments to filter(). The arguments can simply be made available in the scope of the filter callback. However, arguments is special; it refers to the arguments of the current function. There is no way to refer to the arguments of some other function, such as the outer function. Therefore, there is no alternative but to save the arguments under a different variable name (such as args) in the outer function; then you can refer to that variable from within the callback, because the callback "closes" over that variable.
If you're really intent on "passing" the list of numbers to be destroyed to the inner function, instead of just letting it access them by referring to a variable created in the outer scope, then yes, in theory you could use thisArg:
function destroyer(arr/*, number to destroy*/) {
return arr.filter(do_not_destroy, arguments);
^^^^^^^^^ PASS thisArg
}
Now we can define do_not_destroy as
function do_not_destroy(elt) {
return [].slice.call(this, 1).indexOf(elt) === -1;
^^^^ REFER TO thisArg (arguments)
}
Note two things here. First, we refer to the list of arguments as this, because we passed them to filter using thisArg. Second, we cannot write this.slice..., and instead must write [].slice.call(this... , because this is an arguments object, which is not a "real" array and does not have the slice method.
To make do_not_destroy independent of the fact that its parameter is a special arguments object, with an extra parameter (the array) at the beginning, we could do the conversion to an array within the destroyer function:
function destroyer(arr/*, number to destroy*/) {
return arr.filter(do_not_destroy, [].slice.call(arguments, 1));
}
Now we can define do_not_destroy as
function do_not_destroy(elt) {
return this.indexOf(elt) === -1;
}
But now we are basically back to where we started. Instead of "passing" the list of values to be omitted by merely letting the inner function (callback) refer to a variable set in the outer scope, we are passing them to the callback using the back-door thisArg mechanism. I don't really see the point in this.

Explaining the benefits of using a high-order function in a simple English language

Consider this example, i need to know the benefits of using a high-order function as so:
function bind(func, object) {
return function(){
return func.apply(object, arguments);
};
}
I mean what's the problem with a simple function like so:
function bind(func, object) {
return func.apply(object, arguments);
}
This
function bind(func, object) {
return func.apply(object, arguments);
}
returns a result of func invocation. While bind should return a new function, which when called will be invoked in proper context (object).
The benefit in your example is that you get partial application:
Intuitively, partial function application says "if you fix the first arguments of the function, you get a function of the remaining arguments". For example, if function div stands for the division operation x / y, then div with the parameter x fixed at 1 (i.e. div 1) is another function: the same as the function inv that returns the multiplicative inverse of its argument, defined by inv(y) = 1 / y.
The practical motivation for partial application is that very often the functions obtained by supplying some but not all of the arguments to a function are useful; for example, many languages have a function or operator similar to plus_one. Partial application makes it easy to define these functions, for example by creating a function that represents the addition operator with 1 bound as its first argument.
In your example, there's three pieces of information:
which object
which method to call
which arguments to supply to that method call
Using your bind, you can decide on 1 and 2, while leaving 3 for later.
See Underscore for another example that generalizes partial application beyond just this.

Passing "extra" arguments to a function stored in a variable - Javascript

I'm new to Javascript, I'm self-teaching, so this might be an obvious area, but no matter how I phrase the question I can't really seem to get my head around this one issue. At the moment I'm reading through http://eloquentjavascript.net/chapter6.html (which was on mozilla's MDN). I've come across this a couple of times now, I would just like a simple break down if possible.
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));
I don't understand how at the very last step isNotNaN (a variable) is passing an 'extra argument' (NaN) to the function stored in isNotNaN (negate(isNaN). "show(isNotNaN(NaN));"
I came across this same problem when the concept of enclosure was trying to be explained. But I don't get where this argument "NaN" is going in the above function, as it seems to me like the last statement ends up something like:
show(negate(isNaN, NaN));
I would be happy to provide more details. This concept of passing an extra argument to a variable already holding a function with an argument confuses the hell out of me!
There's no "extra" argument. The negate() function itself returns a function defined as a function expression, which can then be called with any number of original (not extra) arguments passed. A closure is used for the returned function to keep a reference to isNaN as func.
var isNotNaN = negate(isNaN);
At this point, isNotNaN contains a reference to the function
function(x) {
return !func(x);
};
Again, func here refers to the isNaN argument passed to the negate function, which is the immediate parent in the scope chain. The result is similar, but not the same as
var isNotNaN = function (x) {
return !isNaN(x);
};
The reason it is not the same is, if we change the value of isNaN, the behaviour of this function will change. In the example you posted, however, the value of func is equal to the original value of isNaN and cannot be changed by anything outside of its scope thanks to the closure.
Essentially, you can pass in any function and get a new function that returns the negated result of the original function in return. For example:
var isNotArray = negate(Array.isArray);
isNotArray(12);
//-> true
In fact, negate(isNaN) simply return a function to the variable isNotNaN. This function take a parameter (named x in your case), then execute the function isNaN on the parameter before negating it and returning the result.
Perhaps this example can clear some things out for you regarding closures:
function foo(x){
function bar(y){
return x+y;
}
return bar;
}
var fooRef = foo(1); // fooRef references foo() with x set to 1
console.log(fooRef(2), foo(1)(2)); // 3, 3
http://jsfiddle.net/ePwy8/

How come func is called from a function?

function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));
This is from a javascript book I'm reading. func is used as a function with the argument x and the negate sign preceding it. How come?
The negate function accepts a function as an argument and returns a new function it creates that, when called, will call the original function with the argument you give it, negate that function's return value, and return that negated value.
negate is used to create a function we assign to isNotNaN that, when called, will call isNaN with whatever argument you pass it and negate the result.
So when you call isNotNaN with NaN, isNotNaN calls isNaN(NaN), which returns true. isNotNaN then negates that, getting false, and returns that value.
Using functions that work on functions is a concept that everyone struggles with at first, so don't beat yourself up. But once grokked, it can be a incredibly powerful tool.
One of the staples of functional programming, that is also valid in JavaScript, is that functions are no different from other primitives, like numbers. They are, in layman's terms, things you can do stuff with. Numbers can be added, subtracted, negated, and functions can be applied, combined, convoluted.
So we can have a function called add that will add two numbers, and we can have a function combine that combines two functions, like this:
//add is a function with two parameters that are numbers
//add's result is a number
var add = function (first, second){
var result = first + second
return result;
}
//combine is a function with two parameters that are functions with one parameter
//combine's result is a function with one parameter
var combine = function (first, second){
var result = function(x) { return first(second(x)); }
return result;
}
As you can see, these two methods are more or less identical in structure. They will be called like this:
add(1, 2); //result is 3
var double = function (x) {return x*2};
var square = function (x) {return x*x};
// result is a function that returns a double of the square
var squareAndDouble = combine(double, square);
squareAndDouble(3); //result is 18
So now, let's deconstruct your example:
function negate(func) {
return function(x) {
return !func(x);
};
}
This is a function called negate that takes a parameter called func. func is a function of one parameter and it's result is a boolean. That's needed in order for func(x) to be a legal expression, and why !func(x) is legal.
In the body of negate a new function is constructed. This function does not have a name, nor does it need one, because we are constructing and returning it. Whoever calls the negate function should take care of the naming (I'll call it the result function). Essentially, this is an equivalent form of the negate function, one that I personally prefer in my code:
function negate(func) {
var result = function(x) {
return !func(x);
};
return result;
}
The result function will take a single parameter called x, and it will return the value of the !func(x) expression, essentially negating the value returned from func, i.e. if func(x) returns a truthy value, the result will be false, and vice versa.
That is why, when we call the negate function, providing it with the [isNaN][1] function (that does indeed take a single parameter, and returns a boolean value), we get back a function that does the opposite of isNaN. That (nameless) function is accommodated in the isNotNaN variable.
Now, since that variable holds a function, we can execute is just like a normal function, and isNotNaN(NaN)) will return false.
isNotNan(Nan) => !isNaN(NaN) => !true => false

Categories

Resources