How come func is called from a function? - javascript

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

Related

Function returning function and no reference

My question is about this function:
function d() {
function e() {
alert('E');
}
return e;
}
d()();//alerts 'E'
When function d is called first time function e is returned, however, nothing holds reference to the returned value( function e in this case), and this returned value should be lost. So, how does this d()() work ? It's not a closure according to my understanding. Thank you !
The call to d (which is d() in that last line) returns e, and then the last () immediately calls that function.
Consider
function n() { return 5; }
console.log(n() + 1); // 6
Nothing holds the return value from the call to n(), and yet the return value can be used in the addition operation. The return value from the call to d() can similarly be used as a reference to a function in a function call expression, which is exactly what happens in your code.
To put it another way, d() returns a reference to a function (e). In order to call a function, all you need is a reference to a function taken from somewhere, and a parenthesized argument list. That's what d()() gives you.
You don't need a named reference to a function in order to use it. You can apply an operator to the result of any expression in place, and the () function call is just another operator.
So it's little different from performing addition on the result of a function call.
function returnTwo() {
return 2;
}
console.log(returnTwo() + 40);
Here we don't store the result of returnTwo(), but we can still use it as the left operand of the + operator. So with the function call in your example, you're doing the same thing.
function d() {
function e() {
alert('E');
}
return e;
}
d()();
//alerts 'E'
It doesn't need a reference because it is explicitly transformed into the returned value. Unless stored, the result of a JavaScript Expression( a sequence of interpreted variables, functions, and/or operations that returns a value ) will be fully evaluated and then removed from memory. The key is that it has to be fully evaluated. You can almost think of functional execution as horizontal Russian Nesting Dolls. The JavaScript expression is:
d()();
So it begins left-to-right with:
d()
which is executed and returns:
function e() { ... }
which turns the line into:
function e() { ... }()
which is then executed, alerts, and returns:
//nothing
The full Expression is completed. There is nothing left for it to do. The reference isn't stored anywhere and immediately after this expression is resolved everything that was returned from its evaluations is thrown away.

How can I log the result of a function that returns a function?

I'm trying to log a function that returns the result of a function as so:
function rutRow(x){
return function(){
return x;
}
}
console.log(rutRow(4)); // expect 4, getting function(){ return x; }
It is call currying. When you call rutRow(4) it retuns another function not value. Let's do it with adding an extra parenthesis () for your case to get the expected data 4
Currying Named after Haskell Brooks Curry, currying is the process of breaking down a function into a series of functions that each take a single argument.
It works like this way,
It accepts one argument and returns one function. The returned
function also accepts one argument and also returns another function
that also accepts one argument and …
function rutRow(x) {
return function() {
return x;
}
}
console.log(rutRow(4)());
See more: https://hackernoon.com/currying-in-js-d9ddc64f162e

what happen when we pass arguments inside the function itself?

Kindly Accept my apologies for being a beginner in JS.
I stopped studying JS on a point of what is the correct answer of what happen inside a function when passing arguments, let us describe by code snippet.
function myFun(x){
console.log(arguments);
console.log(x);
}
myFun(1);
according to the above example,
is the correct action happened is :
Example 1
when passing calling myFun(1) this will do :
function myFunction(x){
var x = 1
}
OR
Example 2
function myFunction(x,y,z){
x=arguments[0];
y=arguments[1];
z=arguments[2];
}
according to the main documentation, i didn't find the desired approach, what i found in arguments object creation process is that:
Repeat while indx >= 0,
Let val be the element of args at 0-origined list position indx.
which I couldn't specify this related to the process of assigning the values or not.
So according to above at all ,
which solution is the correct?
how arguments assigned to parameters? if we passed value 1 as an argument , in the function scope, 1 will be assigned to x or 1 will be assigned to arguments Object?
Let's say you have a function like this:
function oneParam(x)
{
console.log(arguments[0]);
console.log(x);
}
Calling it like so: oneParam(1); will put the first parameter passed in, into the arguments array. If you run the above code, you will get the same value printed twice, because they are the same.
1
1
Now let's take a function with multiple params:
function myFunction(x,y,z)
{
console.log(arguments[0], arguments[1], arguments[2]);
x=arguments[0];
y=arguments[1];
z=arguments[2];
console.log(x, y, z);
}
You will notice, that calling this function like this myFunction("a","b","c"); will produce two similar outputs.
a b c
a b c
So essentially, both scenarios are correct. Just depends on what you passed in when calling the function.
Edit: To clarify, the arguments object will have all the params you passed in. These params will, in order, be assigned to named variables that are there in the function signature.
So you can even have oneParam(1, 2, 3); and the arguments object will have all three params, but only the first param 1 will be assigned to the function variable x.
fiddle here
If you name arguments in your function like this:
function myFunction(x,y,z)
{
console.log(x, y, z);
}
then it's better to access them by their names directly.
You can use argumens if you don't know the number of the arguments while defining the function, like Math.max(), for example.
ES6 makes use of arguments slightly easier than it was before, but it's quite similar. Just remember that arguments is not an array, therefore it has to be converted to an array if you want to have access to all array's methods.
function myFunc_ES6() {
var args = [...arguments];
// or
//var args = Object.values(arguments)
args.forEach(arg => console.log(arg));
}
function myFunc_ES5() {
var args = Array.prototype.slice.apply(arguments);
args.forEach(function(arg) {
console.log(arg);
});
}
myFunc_ES6(1,2,3,4);
myFunc_ES5(6,7,8,9);
The Arguments Object
JavaScript functions have a built-in object called the arguments object.
The argument object contains an array of the arguments used when the function
was called (invoked).
as stated in https://www.w3schools.com/js/js_function_parameters.asp
arguments can be used when you don't want to explicitly specify the parameters of a function. This can be useful in many situations.
Eg.
different behavior on different arguments count
function foo() {
if(arguments.length == 2){
// do something
}else{
//do something else
}
}
extending some method
var oldMethod = Object.prototype.method;
Object.prototype.method = function() {
// some extended functionality
// then call the original
oldMethod.apply(this, arguments);
}
working with unknown number of arguments
function average(){
var i, s=0;
if(!arguments.length){
throw('Division by zero.');
}
for(i=0;i<arguments.length;i++){
s+=arguments[i];
}
return s/arguments.length;
}
Regarding the way the values get assigned,
if we have a function:
function foo(x){}
no matter what you pass in as parameters thiswill be true:
x === arguemnts[0]
It is almost like x is staticaLly referenced in the arguments, because operating on arguments alters the refs too:
arguments[0]++;
x === arguments[0] // true
however deleting the arguments[0] will not modify the explicit parameter value
delete arguments[0]
x !== undefined

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

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.

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/

Categories

Resources