Javascript Nested Function Evaluation - javascript

Hi I am confused with this Javascript function:
var currying = function(a) {
return function(b){
return function(c){
return function(d){
return a + b /c * d;
};
};
};
};
var a = currying(4)(8);
var b = a(2)(6);
console.log(b);
It outputs 28 but I am not sure how did Javascript evaluated the function. I also have learned that a = 4, b = 8, c = 2 and lastly d = 6. Thank you for somebody that will be able to explain the function.

When you use currying you are writing a function that takes one argument, that will return a function taking the next argument until all arguments are supplied.
In this case you need to call the returned function 4 times until you get to the last function and evaluate all the arguments.
This is good because you can pass in arguments at different times during the execution of your code and you can create new functions with arguments already set within the closure of the final functions. eg.
const fourPlusTwo = currying(4)(2)
now you can use the new function fourPlusTwo anywhere in your code and you will have those arguments baked in the closure of the remaining two functions.
The code you have is a non standard example but maybe if you needed to calculate tax throughout your app you could do something like.
const inclusiveTax = rate => amount => {
return '$' + (amount * (rate / (100 + rate))).toFixed(2)
}
const norwayIncomeTax = inclusiveTax(60.2)
const strayaIncomeTax = inclusiveTax(32.5)
const muricaIncomeTax = inclusiveTax(31.5)
console.log(
norwayIncomeTax(50000),
strayaIncomeTax(50000),
muricaIncomeTax(50000)
)
Using just one function you have curried the tax rate for 3 separate countries and returned functions waiting for the amount.

You should know the difference between function object and function call.
like: var a = function(v){return v + 1;} a is a function object. Then a(2) invokes function a.
Try to understand the procedure step by step.
currying is a function which return another function.
so currying(4) returns a function(a is given value 4):
function(b){
return function(c){
return function(d){
return 4 + b /c * d;
};
};
};
};
then currying(4)(8) also is 'var a' returns another function:
function(c){
return function(d){
return 4 + 8 /c * d;
};
};
};
invoking a(2) returns a function object:
function(d){
return 4 + 8 / 2 * d;
};
};
finally a(2)(6) returns 4 + 8 / 2 * 6 which is 28.

This is kind of lexical scoping called Closures
Basically: A closure is a function within function that has access to all parent's variables and parameters. As every parameter in javascript is by default passed by reference, it can even modify parent's variables so you can later execute parent function to see the changes. The great example is jquery's ready function that wraps all other functions within.
You can read more about this here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

This is a very convoluted example of currying - hence the name of the main function.
Currying originates in the field of functional programming and to fully understand it I would suggest that you do some reading, especially as it is implemented in javascript.
To give you some pointers:
In the line:
var a = currying(4)(8);
the first function is called with a parameter of 4; the result of that function call is another function which is then called immediately with a parameter of 8.
Ultimately, all that happens is that the line:
return a + b / c * d;
is executed with the values 4, 8, 2 and 6 for each of the respective variables.
Normal arithmetic rules are applied to give you an answer of 28 (divide first, then multiply and finally add).

Related

Closure with a Lazy Adder Function

I'm stuck on a problem that uses a closure function to add the arguments of subsequent functions into a sum function:
Write a function named: lazyAdder(firstNum). The lazyAdder function
will accept a number and return a function. When the function returned
by lazyAdder is invoked it will again accept a number, (secondNum),
and then return a function. When the last mentioned function is
invoked with a number, (thirdNum), it will FINALLY return a number.
See below for examples!
Example 1:
let firstAdd = lazyAdder(1);
let secondAdd = firstAdd(2);
let sum = secondAdd(3);
console.log(sum); // prints 6
Example 2:
let func1 = lazyAdder(10);
let func2 = func1(20);
let total = func2(3);
console.log(total); // prints 33
I tried:
const lazyAdder = f => g => h => x => f(g(h))(h(x));
Thinking it takes in two function inputs (firstNum + secondNum = sum1), then adds a third (thirdNum + sum1 = sum2).
This did invoke the function twice; however, it did not return the sum - it returned an anonymous function.
If I get it correctly, what you are tasked to do is to perform a sum in a sequence of evaluations (i.e. pass arguments at different times). In a non-lazy approach, you would simply make a function sum which takes 3 parameters x, y and z and sum this: sum(1, 2, 3) = 7. Now to do this the "lazy" way, you have to perform an operation on this function called currying. I suggest reading up on this, as this is essentially what is asked.
Currying such a function can be done quite easily in JavaScript. As you showed, you can just chain the arguments in a function declaration:
const func = arg1 => arg2 => arg3 => ... // Some logic performed here
Now you can call this function 3 times until it returns something other than a closure; a value.
How do you make sure that when you func(1)(2)(3) it returns the sum, which is 6?
Since I suspect this is a homework assignment, I do not want to give you the plain answer. Therefore, it is up to you to define what logic should be put inside the function to sum these values. What is important is that the definition I gave, is already a definition of lazy evaluation.

how do Higher Order function understand a variable which is nod fed through function argument?

I'm trying to understand the mechanism of higher order function in JavaScript.
The example I read from eloquent JavaScript is as below.
function greaterThan(n){
return m=>m>n;
}
const greaterThan10=greaterThan(10);
console.log(greaterThan10(11));
I was wondering how do JS automatically recognizes the variable 'm' which wasn't passed to the function as a second variable in a higher order.
I assumed that any variable defined in a higher order function is reserved for the higher order.
Then I tested it out doing like below.
function greaterThan(n){
console.log(m)
return m=>m>n;
}
It throws an error which means my assumption was wrong.
How do JS prepare itself in a higher order function as it does in the first example.
The code seems like it prepared itself saying
" m is not a parameter passed by its function, however it is going to be passed later on in a higher order."
How did it prepared itself for the higher order function? and why my trial (the second approach) is not working?
Your code annotated below:
function greaterThan(n){
console.log(m); // At this point the below function doesn't exist and has not been called yet
return m => m > n; // You're returning a function here with a parameter named m;
}
When you call greaterThan(10) you're getting a function, which needs two inputs to return a result:
m which resolves when you further call the function returned by greaterThan(10)
n which is is a reference to the greaterThan parameter. It is kept alive (not destroyed by the garbage collector) thanks to the JavaScript's closure mechanism
m in this case is the parameter of the lambda function which is returned by greaterThan.
function greaterThan(n) {
// This is lambda function which uses n from the greaterThan function and has m as a parameter
return (m) => m > n;
}
const greaterThan10 = greaterThan(10);
// This equals to this:
const greaterThan10 = (m) => m > 10;
// Which equals to this:
function greaterThan10(m) {
return m > 10;
}
function greaterThan(n){
return m=>m>n;
// here u are actually returning a arrow fn which will take m as paramater
}
const greaterThan10=greaterThan(10);
// the returned fn reference will be assigned to greaterThan10
// greaterThan10 = m => m>11
console.log(greaterThan10(11));
// here u are passing 11 as a paramater to the arrow fn which u are returning
U are trying to log m before u send the parameter m

Javascript Sequence of Function Example

function makeMultiplier(multiplier) {
var myFunc = function (x) {
return multiplier * x;
};
return myFunc;
}
var multiplyBy3 = makeMultiplier(3);
console.log(multiplyBy3(10));
So I got this example from an online course, the console prints: 30
I don't exactly understand how the value 30 was obtained, below is what I think is how it is executed, but please do correct me if false.
I assume first that the value of multiplier becomes 3, then the function makeMultiplier returns 3 * X.
From here, by assigning var multiplyBy3 = makeMultiplier(3), essentially multiplyBy3 is now a function that returns 3 * X.
Therefore when 10 is plugged in, it returns 3 * 10 = 30.
Yes, you are correct, remember that functions can be passed around to and from variables and other functions.
makeMultiplier returns a reference to a function closure, it doesn't execute it yet.
var multiplyBy3 = makeMultiplier(3); Puts the value 3 into the closure function, and returns a reference to it (still doesn't execute it yet).
At this stage we have:
function multiplyBy3(x) {
return 3 * x;
}
console.log(multiplyBy3(10));
multiplyBy3(10) calls the reference to the closure function and passes in 10.
The example you posted is also referred to as "currying". Here's another javascript example of currying.
I do recommend that you get in the habit of using ES6 syntax. Your example rewritten in ES6:
const makeMultiplier = multiplier => x => multiplier * x;
const multiplyBy3 = makeMultiplier(3);
console.log( multiplyBy3(10) ); // 30
or
console.log( makeMultiplier(3)(10) ); //30
Correct. This is what is known as a 'closure' (a function that returns another function that has access to the scope of the parent function.

What's wrong with my implementation of the memoize function? [duplicate]

I'm trying to use memoization to optimize an explicitly self recursive implementation of the Fibonacci function. The implementation which is fairly standard (a simple and rather naïve implementation though to focus on the actual problem) follows.
Function.prototype.memoize = function () {
var originalFunction = this,
slice = Array.prototype.slice;
cache = {};
return function () {
var key = slice.call(arguments);
if (key in cache) {
return cache[key];
} else {
return cache[key] = originalFunction.apply(this, key);
}
};
};
Now, when creating and memoizing a function as follows, this works1. (Scenario 1)
var fibonacci = function (n) {
return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}.memoize();
console.log(fibonacci(100));
However, the following does not.2 (Scenario 2)
var fibonacci = function (n) {
return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};
console.log(fibonacci.memoize()(100));
And neither does this.2 (Scenario 3)
function fibonacci(n) {
return n === 0 || n === 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci.memoize()(100));
My assumption is that because of the different ways of calling memoize() on the functions, something is changing. Note that the functions are otherwise identical. I suppose that this could be due to the fact that other than in the first instance, only the first call is memoized, not the recursive calls.
Question
If my supposition above is indeed correct, then why is this happening? Can someone explain in detail how the latter two scenarios differ from the first?
1To work in this instance means to return the 100th Fibonacci number since it is only possible to compute it recursively if memoization is used.
2To not work is to crash the browser.
Yes, it's right that only the first call is memoized in the second and third scenarios.
In the first scenario the reference to the original function only exists as a value, then memoize is applied to that and the fibonacci variable contains the reference to the memoized function.
In the second and third scenario fibonacci is a reference to the original function. The value of the expression fibonaci.memoize() that contains the reference to the memoized function only exist as a value before it is called once.
The memoize method doesn't change the original function, instead it returns a new function that wraps the original function. The original function is unchanged, and to use the memoization you have to call the function returned by the memoize method.
In the first scenario when the function makes a recursive call to fibonacci, it's the memoized function that is used. In the second and third scenarios when the recursive call is made, fibonacci is the original function instead.

Javascript: Compose a function with argument placement instructions for each composition

I'm looking for a javascript function that can:
Condition (I)
compose another function when it does not have recursion in its definition, kind of like in maths when the function is given a power, but with multiple arguments possible in the first input - e.g. with a (math) function f:
f(x) := x+2
f5(x) = f(f(f(f(f(x))))) = x+10
Condition (II)
Or maybe even input custom arguments into each step of composition:
(52)2)2=
Math.pow(Math.pow(Math.pow(5,2),2),2) = Math.pow.pow([5,2],2,["r",2]])
//first arg set, how times the next, 2nd arg set - "r" stands for recursion -
//that argument will be occupied by the same function
//Using new solution:
_.supercompose(Math.pow,[[5,2],[_,2],[_,2]]) //-> 390625
2((52)3)=
Math.pow(2,Math.pow(Math.pow(5,2),3)) = Math.pow.pow([5,2],["r",2],["r",3],[2,"r"])
//Using new solution:
_.supercompose(Math.pow,[[5,2],[_,2],[_,3]]) //-> 244140625
_.supercompose(Math.pow,[[5,2],[_,2],[_,3],[2,_]]) //-> Infinity (bigger than the max. number)
Note: The above are just templates, the resulting function doesn't have to have the exact arguments, but the more close to this (or creative, for example, a possibility of branching off like this ->[2,4,"r",4,2,"r"], which would also be complicated) the better.
I've been attempting to do at least (I) with Function.prototype, I came up with this:
Object.defineProperty(Function.prototype,"pow",{writable:true});
//Just so the function not enumerable using a for-in loop (my habit)
function forceSlice(context,argsArr)
{returnArray.prototype.slice.apply(context,argsArr)}
Function.prototype.pow = function(power)
{
var args=power<2?forceSlice(arguments,[1]):
[this.pow.apply(this,[power-1].concat(forceSlice(arguments,[1])))];
return this.apply(0,args);
}
//Usage:
function square(a){return a*a;}
square.pow(4,2) //65536
function addThree(a,b){return a+(b||3); }
// gives a+b when b exists and isn't 0, else gives a+3
addThree.pow(3,5,4) //15 (((5+4)+3)+3)
Worst case, I might just go with eval, which I haven't figured out yet too. :/
Edit: Underscore.js, when played around with a bit, can fulfill both conditions.
I came up with this, which is close to done, but I can't get it to work:
_.partialApply = function(func,argList){_.partial.apply(_,[func].concat(argList))}
_.supercompose = function(func,instructions)
{
_.reduce(_.rest(instructions),function(memo,value)
{
return _.partialApply(_.partialApply(func, value),memo)();
},_.first(instructions))
}
//Usage:
_.supercompose(Math.pow,[[3,2],[_,2]]) //should be 81, instead throws "undefined is not a function"
Edit: jluckin's cleareance of terms (recursion-> function composition)
Edit: made example function return number instead of array
The term you are looking for is called function composition, not necessarily recursion. You can apply function composition in javascript easily since you can pass a function as an argument.
I created a small function called compose, which takes a function, an initial value, and the number of times to compose the function.
function compose(myFunction, initialValue, numberOfCompositions) {
if (numberOfCompositions === 1) {
return myFunction(initialValue);
}
else {
return compose(myFunction, myFunction(initialValue), --numberOfCompositions);
}
}
When this function is evaluated, you pass in some function f(x), some initial x0, and the repeat count. For example, numberOfCompositions = 3 gives f(f(f(x)));
If there is one composition, then f(x) is returned. If there are two compositions, compose returns f(x) with f(x) replacing x as the argument, with 1 passed in as the composition so it will evaluate f(f(x)).
This pattern holds for any number of compositions.
Since functions are treated as objects and can be passed as arguments of functions, this method basically wraps your "non-recursive" functions as recursive functions to allow composition.
Success(simplicity wins):
_.supercompose = function (func,instructions,context)
{
var val;
for(var i = 0; i < instructions.length; i++)
{
val = _.partial.apply(_,[func].concat(instructions[i])).apply(context||this,val?[val]:[]);
}
return val;
}
//Usage (with a function constructor for operations):
_.op = function(o){return Function.apply(this,"abcdefghijklmnopqrstuvwxyz".split("").concat(["return " + o]))}
_.op("a+b")(3,5) //-> 8
_.op("a*b")(3,5) //-> 15
_.supercompose(_.op("(a+b)*c*(d||1)"),[[1,2,3],[-5,_,1],[1,2,_,3]])
//-> (1+2)*((-5+((1+2)*3))*1)*3 -> 36

Categories

Resources