I encountered the following code when I was doing my assignment. I can understand why the the expression (thrice(add1))(0) evaluates to 4. If we define f(x) = x + 1, (thrice(add1))(0) would be evaluated as f(f(f(x))) which is ((x+1)+1)+1. However, I don't quite understand why ((thrice(thrice))(add1))(0) would evaluate to 27, instead of 3*3=9.
//Javascript
function thrice(f) {
return compose(compose(f, f), f);
}
function compose(fun,fun2) {
return function (n) {
return fun(fun2(n));
};
}
function add1(k) {
return k + 1;
}
console.log(((thrice(thrice))(add1))(0)); //27
console.log((thrice(add1))(0)); //3
Inner (thrice):
thrice(1) returns ---> function (n) { return fun(fun2(n));
Outer (thrice):
thrice(1) returns ---> function (n) { return fun(fun2(n));
thrice(1) returns ---> function (n) { return fun(fun2(n));
thrice(1) returns ---> function (n) { return fun(fun2(n));
Outer (add1) introduces the add1 function to the scope.
When the 0's declared, add1 inserts it as k.
The add1 function resolves.
K's now one.
We're now back into the original ()'s.
The variable n's now equal to one.
The function2 or (fun2) becomes add1.
Then outer 'fun' becomes add1.
The whole return of one thrice=3.
The first time the outer thrice happens, the inner thrice returns the three.
The second time it iterates, it's three * three.
Finally with the last time, it's nine * three.
Related
I came across this pattern in redux compose function. I still don't understand how in the example below the functions are evaluated starting from the last and not from the first:
function f2(a) {
return a + a;
}
function f3(a) {
return a + a + a;
}
function f4(a) {
return a + a + a + a;
}
function f5(a) {
return a + a + a + a + a;
}
function compose(...funcs) {
return funcs.reduce(function x(a, b) {
return function y(...args) {
const temp = a(b(...args));
return temp;
};
});
}
const composedFunction = compose(f2, f3, f4, f5);
const result = composedFunction(2);
In the first reduce iteration the accumulator is f2 so we'll get f2(f3(2))=12. In the next iteration we'll call f4(12)=48. In the last iteration we'll call f5(48)=240. So the evaluation order is f5(f4(f2(f3(2)))). But using console.log I see that the evaluation order is f2(f3(f4(f5(2)))) which is also 240 by coincidence.
As far as I understand the function y is called for all array elements so why only the last function gets 2 as the parameter?
Let's step through the code with a very simple example:
compose(f2, f3, f4)
As no initial value was passed to reduce, it will start with the first (f2) and the second (f3) value of the array and call the callback with that, x gets called with a being f2 and b being f3. Now x does'nt do anything, it just returns function y that can access a and b through a closure.
Reduce will now continue to the third element, the first argument being the result of the previous callback (the closured y), and the second argument being f4. Now x gets called again, and another closure is created over y, y gets the finally returned from the whole function.
If we try to visualize thus closured function it'll be:
y { // closure of y
a -> y { // a references another closure of y
a -> f3,
b -> f2
},
b -> f4
}
Now you call that closured y and pass 2 into it, that will call b (f4) and pass the result to the call to a (closured y).
a ( b(...args))
y { ... } ( f4(2) )
Now that closured y will do the same:
a ( b ( ...args))
f2( f3( f4( 2 ) ) )
Hint: It is sometimes really difficult to keep track of closured values, therefore the console provides you with great utilities to keep track of them: Open your code in the consoles "debugger" tab, click on the line numbers where the function calls are to attach breakpoints, then run the code again, the execution will yield whenever a breakpoint is reached and you can see the values of all variables (including closured ones).
The reduce is not calling the functions f2, f3, f3, f5, but it is creating a function from those. This is the value of the accumulator in each iteration. Note that the value is a function and not a result from execution of the function.
1:a=f2;b=f3;return value(NOT TEMP but function y)=f2(f3(...args))
2:a(prev return value)=f2(f3(...args));b=f4;return value=f2(f3(f4(...args)))
and so on....
The compose function can be re-written as:
function compose(...funcs) {
return funcs.reduce(function (a, b) {
return function (arg) {
const temp = a(b(arg));
return temp;
};
});
}
After the first iteration, the returned function which is passed in as the next accumulator is:
function (arg) { // R1
return f2(f3(arg));
}
After the second iteration, the returned function which is passed in as the next accumulator is:
function (arg) { // R2
return R1(f4(arg));
}
And finally, the returned function assigned to composedFunction is:
function (arg) { // composedFunction
return R2(f5(arg));
}
So running composedFunction(2) and going back up the chain:
f5(2) returns 10
R2(10) returns R1(f4(10))
which is R1(40)
R1(40) returns f2(f3(40))
which is f2(120)
which is 240
Hopefully that's sufficient.
It can be written as a single call as:
function composedFunction(arg) {
return f2(f3(f4(f5(arg))));
}
I am under the impression that each time a function is called it is a new instance of that function. How is it that this code can take n and increment it without n being set back to zero each time?
const f = (function()
{
let n = 0;
return function()
{
return ++n;
}
}());
console.log(f()); // prints 1
console.log(f()); // prints 2
console.log(f()); // prints 3
The IIFE is executed just once, and the value is assigned to f. So there's just a single closure, and it has a single n that gets incremented each time you call the returned function.
The result you expect would occur if you wrote:
const f = function() {
let n = 0;
return function() {
return ++n;
}
};
console.log(f()()); // prints 1
console.log(f()()); // prints 1
console.log(f()()); // prints 1
This doesn't use an IIFE, it's just an ordinary higher-order function. Every time you call f you get a new closure.
I am new to JavaScript and have several questions about functional programming.
Here is a statement:
outer(inner(5));
Is it possible to construct function outer in a way that allows it
to capture function inner and its argument 5?
Is it possible to construct function inner in a way that allows it to
pass itself and its argument 5 to function outer?
If the answer to both questions above is no, is it possible to
construct functions outer and inner in a way that allows the former
to capture function inner and its argument 5 or the
latter to pass itself and its argument 5 to function
outer?
I tried:
using the arguments object but to no avail.
function outer (parameter) {
return arguments;
}
function inner (n) {
return n + 1;
}
console.log(outer(inner(5))); // returns Arguments { 0: 6 ... }
using currying but I do not see how it can help me since I am not given the following statement:
outer()(5);
A possible workaround consists in returning an array from inner() composed of on one side the processing function and on the other side the argument.
outer will be able to access both by reading the array.
function outer(arr)
{
var fun = arr[ 0 ];
var arg = arr[ 1 ];
var result = fun(arg);
console.log('inner function is:', fun);
console.log('its argument is:', arg);
console.log('its result is:', result);
return result;
}
function inner(num)
{
return [
function (_num)
{
return _num + 1;
},
num
]
}
console.log(outer(inner(5)));
You could achieve this by letting your inner return a function (foo) which closes over n. You can then let foo return n+1. Then, within your outer function, you can invoke foo to get its return value:
const outer = f => f();
const inner = n => _ => n+1;
console.log(outer(inner(5)));
Alternatively, another possibility would involve changing your return value. You could return an array from inner which contains the original passed through arguments (...arguments) and the returned value (to_return) and then use destructuring assignment to get the passed in argument(s) (n & m) and the returned result:
function outer([result, n, m]) {
console.log("returned from inner: ", result);
console.log("arguments passed into inner: " + [n, m]);
return n;
}
function inner(n, m) {
let to_return = n + 1;
return [to_return, ...arguments];
}
console.log(outer(inner(5, 2))); // returns 5
Note: I added an m argument to demonstrate how you can extend this to multiple arguments
function outer(myFunction, argument) {
if (typeof myFunction !== "function") {
return false;
}
return myFunction(argument);
}
function inner(n) {
return n + 1;
}
console.log(outer(inner, 5));
Just a simple approach. Don’t execute the function inner but pass it as an argument (myFunction). And let the outer function execute it with the given argument.
The following program confuses me very much, the console.log() were added by me.
function add(a) {
console.log("1");
var total = a;
console.log("2");
var _fn = function (b) {
console.log("3");
total += b;
console.log("4");
return _fn;
};
console.log("5");
_fn.toString = _fn.valueOf = function () {
console.log("6");
return total;
};
console.log("7");
console.log("_fn: " + _fn);
return _fn;
}
When I ran add(1)(2), console showed:
1
2
5
7
6
_fn: 1
3
4
6
ƒ 3
My questions are:
1) in var _fn = function (b) {...}, what does _fn refer to in "return _fn" statement? If it refers to itself, then isn't it in infinite recursion like this
var _fn = function (b) {
total += b;
return function (b) {
total += b;
return function (b) {
total += b;
return _fn;
.
.
.
}
}
}
2) In console, it showed "_fn: 1" which means 1 was returned, but apparently, _fn (the function) was returned so that the calculation could keep going. So there is a conflict between the actual returned _fn and the value shown in console.
in var _fn = function (b) {...}, what does _fn refer to in "return _fn" statement?
The return statement says the when this function is called, the return value from the function will be (a reference to) the function object itself. Note it returns the function object, without calling it. Just the object, no call. At least not yet anyway....
If it refers to itself, then isn't it in infinite recursion like this ...
No, because the return value, the function, is not immediately called. It's kind of like doing this:
function g() {return g}
g()
Running that does not go into an infinite loop. You call the function g, and you get back g. You can do g()()()()()()() yourself, but that still "stops." Recursion is when a function calls itself, not returns itself!
In console, it showed "_fn: 1" which means 1 was returned, but apparently, _fn (the function) was returned so that the calculation could keep going. So there is a conflict between the actual returned _fn and the value shown in console.
Well, it's probably not correct to say 1 was returned; instead the code forces all console.logs (and similar) to produce the current value of total. At the time you did your console.log, total had the value of your first argument, namely 1. You were pretty smart to print out all those numbers, so it should help your understanding. Check out that after the 7 was printed, you had not yet done the subsequent call in which the addition was done. That's why you saw 1.
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;
}
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?)