JS, return function name - javascript

I've just started to learn javascript and come across one task that I don't understand. Can anyone explain me why do we return function name "return f" in this example and what for do we use "f.toString"?
function sum(a) {
var currentSum = a;
function f(b) {
currentSum += b;
return f;
}
f.toString = function() {
return currentSum;
};
return f;
}
alert( sum(1)(2) ); // 3
alert( sum(5)(-1)(2) ); // 6
alert( sum(6)(-1)(-2)(-3) ); // 0
alert( sum(0)(1)(2)(3)(4)(5) ); // 15

Lets start with a simplified version:
function sum(currentSum) {
return function f(b) {
currentSum += b;
return f;
}
}
It willwork much like yours, you can do:
sum(1)(2)(3);//f
sum(1)(2);//f
However, they always return a function, so were not able to access the currentSum. Its in sums scope and as its never returned or passed, its impossible to get it. So we probably need another function we can call to get the current sum:
function sum(currentSum) {
function f(b) {
currentSum += b;
return f;
}
f.getSum = function() {
return currentSum;
};
return f;
}
So now f has a property (functions are objects too), which is a function called getSum to get our variable
sum(1)(2)(3)//f
sum(1)(2)(3).getSum()//6 <= wohhooo
But why do we call it toString ?
When adding a variable to a string, its converted to a string, e.g.
1+"one"//"1one"
the same applies to objects/functions, but in this case, the js parser tries to call their toString method first, so:
sum(1)(2)+"three"
equals
sum(1)(2).toString()+"three"
the same conversion happens when passing non strings to alert.

You are returning the object. So you can call the function again and, in the second call, you will have a currentSum allready.
when you do sum(3) the function will hold the number 3 and when you call it again doing sum(3)(4) it will add 4 to the currentSum.
then the alert will call the toString method and it will print the sum

look at the first example
alert( sum(1)(2) ); // 3
sum(1) // will return f. sum must return a function in order for the syntax to work
after it will return f it will become:
alert( f(2) );

With function sum you are passing the first argument a and returning function f which sum currentSum with the argument passed to f (b) and return again f and you can do that many times you want at the end it will call alert function which needs its first argument to be string. For that purpose you have rewritten the method on function f toString which in this case will return the currentSum.
Every object has a toString() method that is automatically called when the object is to be represented as a text value.

This is the task for understanding the type system of JavaScript. The task is to make function that adds numbers using currying. The idea is to make function that adds numbers when called like this sum(1)(2)(3), as you written in the task.
What do we do (looking to your code) in function sum:
1.
var currentSum = a;
Here you declare a sum variable in scope of function sum.
function f(b) {
currentSum += b;
return f;
}
Then you declare the function that will perform summation. It returns itself for possibility of doing such thing: f(1)(2)(3)
3.
f.toString = function() {
return currentSum;
};
After that you declare that f, converted to string returns sum value
Than you return f to start adding.
Than what about f.toString - it 's being called, when f is passed alert as an argument. That's automatic casting of javascript

Related

Why does this function return a string and not the sum?

function sum(a){
if(!a) return 0;
return b=>a + sum(b);
}
console.log(sum(2)(3)); // returns a string "ab=&gta + sum(b)"
console.log(sum(2)(3)()); // says sum (..)(..) is not a function
Is there a particular reason this is happening?
When you write:
console.log(sum(2)(3));
this can be re-written to be:
const fn = sum(2);
console.log(fn(3));
If you look at what sum(2) returns, it will return another function:
return b=>a + sum(b);
You then invoke this function using fn(3), you perform:
2 + sum(3)
When you call sum(3), you again return the same above function, so you are doing:
2 + function
Since addition doesn't work between a number and a function, JS will try and convert the function to a primitive by calling .valueOf() on your function. Calling .valueOf() on a function will return it's string version, hence making 2 + function perform concatenation between your function and the number 2, giving you:
2b=>a + sum(b)
Your second attempt of sum(2)(3)() tries to invoke this string, and so you get an error when you try and treat the string as something callable.
You don't need sum(b) in the return statement, just b
function sum(a){
if(!a) return 0;
return b=>a + b;
}
console.log(sum(2)(3));
If you want indefinite chaining of curried functions, see this question: Variadic curried sum function
Maybe try this:
function sum(a, b){
if(!a) return 0;
if(!b) return a;
return a + b;
}
console.log(sum(2,3));

How Javascript `reduce` performed on function array achieves function composition?

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))));
}

Create a function with an undetermined number of successive calls

As part of a programming challenge, we are tasked with creating a function with an undetermined number of successive calls. As an example, let's say the function returns simply the sum of the provided arguments, it should work as follows :
sum(4)() // 4
sum(4)(5)() // 9
sum(4)(5)(9)() // 18
sum(4)(5)(9)(1)() // 19
// etc...
The problem is simplified by the allowed empty function call at the end as an indication of end of calls.
I have worked on a solution that does the job but using global variables inside the function itself :
var sum = function (a) {
if (!sum.init) {
sum.total = 0;
sum.init = true;
}
if (!arguments.length) {
sum.init = false;
return sum.total;
}
sum.total += a;
return sum;
};
This solution works but uses state, global variables and function object trickery which is not ideal. My question here is whether there is a way to solve the problem in a purely recursive way.
As a side note, I do not believe the problem can be solved if that last empty call () is not provided, but if I'm wrong please let me know.
Update
This issue has been answered in CodeReview : https://codereview.stackexchange.com/a/153999/129579
A neet solution that does not rely on global scope and is purely functional.
You can make use of closures to acheive what you want like this:
function sum(value){
// the closure variable that will be accessible for all the _sum calls (initialised to 0 for every sum call).
var result = 0;
// the function that will be returned (sum will only get called once to initialize the result to 0. It's _sum which will be returned as much as possible)
function _sum(a){
// if we passed a parameter, then add it to result and return a new _sum
if(typeof a != "undefined"){
result += a;
return _sum;
}
// if we didn't return the result
else
return result;
}
// of course after initializing result we need to call _sum that handle the actual summing and return whatever it returns (if value is defined, it will return another `_sum` if not it will return the value of result which will be 0 at first) from now on sum will have nothing to do with the rest of the calls (()()()... )
return _sum(value);
}
console.log("sum() = " + sum());
console.log("sum(7)() = " + sum(7)());
console.log("sum(5)(6)(7)() = " + sum(5)(6)(7)());
// will return 0 because we call sum again
console.log("sum() = " + sum());
NOTE: That sum(1)(7)(3)()); will call, in this order:
sum with the parameter 1 which will initialize result to 0 and call
_sum with the same parameter 1 which will add it to result and return a new inctance of _sum which will be called so the following
_sum get called with the parameter 7, add it and return a new _sum so the new
_sum get called with the parameter 3, ... spawn another
_sum that will have no parameter, therefore if(typeof a != "undefined") will fail and this _sum will return result instead.
The actual sum is only called once at the begining to do the initialization. It's, as I said, _sum that get chained after that all the way to the end.
Basically you could use an outer function sum for the initial call and a closure over the starting value a and an inner function fn, which is repeatingly returned and only exited if arguments.length is equal to zero.
If a value b is supplied, the variable a gets updated and the inner function fn gets returned.
function sum(a) {
return function fn(b) {
if (!arguments.length) {
return a;
}
a += b;
return fn;
};
}
console.log(sum(1)());
console.log(sum(1)(2)());
console.log(sum(1)(2)(3)());
Edit for calling sum with no argument
function sum(a) {
return arguments.length ?
function fn(b) {
if (!arguments.length) {
return a;
}
a += b;
return fn;
} :
0;
}
console.log(sum());
console.log(sum(1)());
console.log(sum(1)(2)());
console.log(sum(1)(2)(3)());

How the parens work?

I have found a piece of code in my teacher s notes and I do not understand it.
The point is to find the value for "pass" for which the function would return TRUE.
Can you please answer to my questions below(comments), so I can understand how this works?
<script type="text/javascript">
function findPassword(pass)
{
var b = 1337
//How is this function returning "min" (without the parens?)
function add(x){
b += 84
return min
}
//Same question as above...for "mod" - how is this compiling?
function min(x){
b -= 123
return mod
}
function div(x){
b /= 3
return min
}
function mod(x){
b = b+5+(b%3)
return add
}
//what is the purpose of "fn" if it is not used at all?
var fn = function ()
{
b += 34
return div
}
//WHAT is happening here? "() () ()"
(function (){
b /= 3
return mod
})()()()
if(pass == b*b) {
return true;
} else {
alert("Wrong password !")
return false;
}
}
</script>
So looking at this:
(function (){
b /= 3
return mod
})()()()
You have this:
function (){
b /= 3
return mod
}
Which is a function. You wrap it in brackets and then call it with (), this is called a immediately invoked function expression (IIFE).
So what does it return? It returns mod, which is a function, so the next () will call that function.
What does mod return:
function mod(x){
b = b+5+(b%3)
return add
}
It returns the function add, which you invoke again with (). The function add happens to return the function min, but since we have no more (), we don't invoke it, so it's basically thrown away.
Now, none of this is to suggest this is a good way to structure your code, because it isn't.
As for what value will actually make findPassword return true? Well, you could follow what happens to b in each function.
...or, you could just stick a console.log(b); right after the IIFE to see it's value. The value of pass you need will be that number squared.
Just because nobody pointed out what the purpose of the function fn in this example is:
At first sight, it may seem that you've got an anonymous function self executing, and starting a chain of execution by doing so, however, that encapsulated anonymous function, and add, are actually the only functions in the code that don't execute, and that is because the declaration of fn, before it, is missing a semicolon:
var fn = function ()
{
b += 34
return div
} // <- missing semicolon.
// Because of this, the `var` statement doesn't stop in here.
Because of that missing semicolon, the parentheses encapsulating the anonymous function that comes after this function declaration, are actually executing fn, and passing the anonymous function as an argument to it (and fn is doing nothing with that argument). So, in reality, the code looks like this:
var fn = function ()
{
console.log(arguments[0]); // Logs the anonymous function
b += 34
return div
}(function (){
b /= 3
return mod
})()()()
// The parentheses () mean 'execute' this.
// If they are chained, they execute what the previous
// function returned.
// It is possible to do that when, like in this code, the functions
// return a function reference (meaning, the name of a function).
Which is pretty much the same as this:
var fn = function () {
b += 34/= 3
return div
}( /* Executing fn... */ )( /* div */ )( /* min */ )( /* mod */ )
// fn ends up containing a reference to add, because mod returns that,
// but add is never called.
console.log(fn === add); // true
The chain of execution is this:
fn => div => min => mod
So, to arrive at the password, you do:
var b = 1337;
b += 34;
b /= 3;
b -= 123;
b = b + 5 + (b%3);
// b === 340
// password is b^2: 340 * 340 = 115600
Of course, you can also console.log b, but what's the sense of that?
Follow the return statements and you'll see that they are functions, therefore adding () to that return value will evaluate it.
The first set of parens executes the function immediately before it. This returns mod which is a function. It gets executed by the second parens. This (mod) returns add which is, again, a function. So the last set of parens executes add. Which, in the end, returns min.
It's not very clear the way this program is running but it's essentially modifying that one variable and returning more functions to simulate some logic that modifies the variable in different ways depending on how you call the functions.

why this javascript decorate function doesn't work?

I am looking at decorate function. For example, decorate function can make sum() function to return a double sum. But the following code doesn't work as desired, I changed the 'f' to 'sum', please see comment on relevant line, why I cannot change this?
<script>
function doublingDecorator(f) {
return function() {
return 2*sum.apply(this, arguments); // the original code is: return 2*f.apply(this,arguments) I changed to sum, then doesn't work.
}
}
// Usage:
function sum(a, b) {
return a + b
}
var sum = doublingDecorator(sum); // sum gets decoration
alert (sum(3,4)); //return 14
</script>
f in doublingDecorator is not used. Instead you reference sum, which you also redefine. This causes an infinite loop.
function doublingDecorator(f) {
return function() {
return 2*f.apply(this, arguments);
// ^-- f instead of sum!
}
}
function sum(a, b) {
return a + b
}
var sum = doublingDecorator(sum); // note: sum is already declared here, redeclaring is technically wrong.
console.log(sum (3,4)); // 14
Two things:
You changed the inner f.apply to sum.apply.
You redefine sum.
That's why it's breaking. Your change makes it a recursive call that never ends (infinite recursion) because sum calls itself over and over again. This is because you reference sum inside, which you have also redefined.
Eventually the recursion ends up exceeding the maximum call-stack size.
I recommend leaving f.apply as it is. Then your code should work. Another option is to not redefine sum. So do this instead:
var newSum = doublingOperator(sum);
console.log(newSum(3, 4)); //returns 14

Categories

Resources