Javascript function is not working properly - javascript

I'm trying to assign this function to this variable but no matter what i try nothing works and it gives me this error TypeError: addSix is not a function
const createBase = num => {
num + 6
}
let addSix = createBase(6);
addSix(10); // returns 16
addSix(21); // returns 27
Any suggestions please?

For addSize to be a function, the return value of createBase must be a function.
createBase doesn't return anything. It has no return statement. Consequently, it returns undefined.
It doesn't even create a function to return.

There are a couple of different problems:
createBase is a function that doesn't return anything.
The part that you're trying to create as a function (num => { num + 6 }) should either not have {} or should have a return (more here).
You're hardcoding the 6, but you should be using the parameter value passed to createBase.
You need to make createBase a function that returns a function:
// `createdBase` vvvvvvvvvvvvvvvvvvvvvvvvvvv
const createBase = num1 => num2 => num1 + num2;
// The func it returns ^^^^^^^^^^^^^^^^^^^
let addSix = createBase(6);
console.log(addSix(10)); // returns 16
console.log(addSix(21)); // returns 27

First things first; num => { num + 6 }. If you're using curlies, you have to add the return statement. Otherwise, lose the curlies: num => num + 6. This will implicitly add a return statement.
Then,
If you're not used to working with closures, I advice you not to use arrow functions.
And while this may work
const createBase = (num) => (num) => num + 6;
let addSix = createBase(6);
console.log(addSix(10));
console.log(addSix(21));
It's far more clear what it does for javascript beginners when you type it out like this;
const createBase = function(num) {
return function (num) {
return num + 6;
}
};
let addSix = createBase(6);
console.log(addSix(10));
console.log(addSix(21));
What you had was the following, which if written out, makes it clear addSix was assigned the value of num+6 instead of being a function.
const createBase = function (num) {
return num + 6
};

There are two issues:
Issue 1:
You need to use a return statement or remove the curly brackets:
const createBase = num => num + 6;
Issue 2:
createBase(6) returns a number not a function.
Therefore you can't pass arguments to a number.
Example:
const createBase = num => num + 6;
let addSix = createBase(6); // this is a number, not a function
addSix(21); // you can't call a number with arguments as function and hence the error
addSix is a number, you can't pass arguments to it and use it as a function because it is not.

It seems like you want to create a single argument fucntion that returns a single argument function, which could be achieved like this.
const createBase = base => (num) => base + num;
let addSix = createBase(6);
addSix(10); // returns 16
addSix(21); // returns 27
Also see:
Partial application
Currying
(They're not quite the same: What is the difference between currying and partial application?)

Related

What means the comparison between empty parantheses without a function and content of curly brackets [duplicate]

I'm new to both ES6 and React and I keep seeing arrow functions. Why is it that some arrow functions use curly braces after the fat arrow and some use parentheses?
For example:
const foo = (params) => (
<span>
<p>Content</p>
</span>
);
vs.
const handleBar = (e) => {
e.preventDefault();
dispatch('logout');
};
The parenthesis are returning a single value, the curly braces are executing multiple lines of code.
Your example looks confusing because it's using JSX which looks like multiple "lines" but really just gets compiled to a single "element."
Here are some more examples that all do the same thing:
const a = (who) => "hello " + who + "!";
const b = (who) => ("hello " + who + "!");
const c = (who) => (
"hello " + who + "!"
);
const d = (who) => (
"hello "
+ who
+ "!"
);
const e = (who) => {
return "hello " + who + "!";
};
You will also often see parenthesis around object literals because that's a way to avoid the parser treating it as a code block:
const x = () => {} // Does nothing
const y = () => ({}) // returns an object
One can also use curly braces to prevent a single line arrow function from returning a value -- or to make it obvious to the next developer that a single line arrow function shouldn't, in this case, be returning anything.
For example:
const myFunc = (stuff) => { someArray.push(stuff) }
const otherFunc = (stuff) => someArray.push(stuff)
console.log(myFunc()) // --> logs undefined
console.log(otherFunc()) // --> logs result of push which is new array length
Parenthesis are used in an arrow function to return an object.
() => ({ name: 'YourName' }) // This will return an object
That is equivalent to
() => {
return { name : 'YourName' }
}
Actually in a briefcase when somebody uses braces in an arrow function declaration, it is equal to below:
const arrow = number => number + 1;
|||
const arrow = (number) => number + 1;
|||
const arrow = (number) => ( number + 1 );
|||
const arrow = (number) => { return number + 1 };
Parenthesis has an implicit return statement while curly braces you need an explicit return statement
If you use curly braces after the arrow to define the function body, you have to use the 'return' keyword to return something.
For example:
const myFun1 = (x) => {
return x;
}; // It will return x
const myFun2 = (x) => {
x;
}; // It will return nothing
If you use the parenthesis, you don't need to mention the 'return' keyword.
For example:
const myFunc1 = (x) => x; // It will return x
const myFunc2 = (x) => (x); // It will also return x
In your first example, the right-hand side of the arrow function shows a single expression that is enclosed by a grouping operator:
const foo = (params) => (
<span>
<p>Content</p>
</span>
);
A similar comparable case would be the following:
const foo = (params) => (<span><p>Content</p></span>);
A distinction, in the above cases using single expressions, is that the right-hand side is the returned value of the function.
On the other hand, if you use curly braces, JavaScript will understand that as a statement:
const foo = (params) => {} // this is not an object being returned, it's just an empty statement
Therefore, using statement is a good start for you to have code in it, multiple lines, and it will require the use of "return" if the function is intended to return value:
const foo = (params) => {
let value = 1;
return value;
}
In case you wanted to return an empty object in the shortest form:
const foo = (params) => ({})
See tests
To answer a duplicate post(question posted here), just for reference for others:
var func = x => x * x;
// concise body syntax, implied "return"
var func = (x, y) => { return x + y; };
// with block body, explicit "return" needed
For reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Function_body
Also note:
If you are returning an object literal as the result from a fat arrow function, then you must enclose the object in parentheses, e.g., myFunc = () => ({ data: "hello"}). You will receive an error if you omit the parentheses because the build tools will assume that the curly braces of the object literal are the start and end of a function body.
Every function has 2 aspects.
First of them is that each one, not just the arrow functions, has an execution context (a block scope) in which the variables are created and used.
In other words, inside the curly braces { ... } of the function, what is declared and assigned there, stays there and is not visible to the outside functions / or variables.
For example, when writing something as
let x = 100;
function doSomething() {
let x = 50;
console.log(x);
}
doSomething(); // 50
console.log(x); // 100
both values are displayed in console (instead of 'x from outside just being replaced by x from inside the function').
You see that despite of let not usually allowing other variable x to be declared again (with the same name x), in this case, because the second x is declared and initialized inside the { ... }, it does not alter the outside one, which also happens because after the function doSomething is called, the x from inside of it is created, assigned, printed in console and then destroyed (deleted from the memory). So that process happens every time we call that function by running doSomething() .
So this is the first aspect to take into consideration when understanding the functions: they execute then forget the values created by the code inside their curly braces.
Because of it, it's easier to understand their second aspect -- as functions cannot just work isolated from the others, they need to also send data to the others, so they have some 'reporting aspect' used to externalize some part of the results computed inside their curly braces, which is exactly why the return statement exists.
Return exists in each function, even in the console.log or alert(), even in doSomething(), but in these cases where we didn't explicitly set something for it, it is always 'return undefined'.
Therefore it isn't necessary to write it, but instead know that where you don't return something specific, the function itself will do it for you by returning undefined.
When you write (or use) a function meant just to execute something, it will also return undefined. Always.
You can check that thing with every function which (apparently) has no declared return:
let x = alert(100);
console.log(x); // undefined
let y = doSomething(); // console prints 50
console.log(y); // 50, then undefined --- 2 lines
console.log(alert('Hello')); // undefined
console.log(console.log('Okay')); // Okay , then undefined
Why is that?
Because alert() which is a method of global object window (in browser) (so it is actually window.alert() ) and also console.log() (which is the same with window.console.log() , too), execute something (printing in an alert box or in the console whatever is in between the () AND THEN return undefined).
Now, coming back to the arrow functions, they are not just some new way of notation for writing the functions but they also have some specific features.
First, if you only have a parameter between the () in an arrow function, you can write it without the parentheses.
Second, if inside the curly braces there's a single statement, you can omit as well the curly braces.
Third one, if the single statement is a return statement, you can omit the word return.
Somehow, using these we could transform many usual functions into arrow functions if needed:
function doSomething() {let x = 50; console.log(x);} // as function declaration
let doSomething = function() {let x = 50; console.log(x);}; // as function expression, which is an anonymous function assigned to the variable 'doSomething'
let doSomething = () => {let x = 50; console.log(x);}; // as arrow function
// let's transform it further
let doSomething = () => {console.log(50)}; //
// that is equivalent to ---- let doSomething = () => {console.log(50); return undefined};
// or even to ---- let doSomething = () => {return ( console.log(50) ) };
// because anyways, *console.log* has *return undefined* in it, as explained above
//which is the same as ---- let doSomething = () => {return console.log(50) };
// let's now apply the rules 2 and 3 from above, one by one:
let doSomething = () => return console.log(50);
let doSomething = () => console.log(50);
// Obviously, this just shows how we could rewrite many usual functions (functions declarations) into arrow functions
// we can do that safely if we don't have any **this** involved in the functions, of course
// also, from all lines of code above only one must remain, for example the last one.
// the last one, despite only having ---- console.log(50) --- as the execution aspect, it also ---- returns undefined ---- as well
// obviously ---- console.log( typeof doSomething ); // function
// while ---- console.log( typeof doSomething() ); // undefined
If an arrow function has 2 or more parameters, we cannot omit the parentheses around them:
function sum(a, b) {let total = a + b; return total}
let sum = function(a, b) {let total = a + b; return total};
// or
let sum = (a, b) => {let total = a + b; return total};
// or
let sum = (a, b) => {return a + b};
// or
let sum = (a, b) => a + b;
For simple operations as above, the fat arrow sign '=>' can be "read" as is transformed into, in other words, a and b is (are) transformed into a + b.
Opposite to that, there are also functions that validate some data (for example checking the data type, etc), like this one
let isNumber = x => typeof x === "number";
// or
let isNumber = (x) => {return (typeof x === "number")};
// obviously,
isNumber("Hello, John!"); // false
Those DON'T transform the data, and thus the arrow sign can be read something more as with the condition that, or similar.
In other words, a function like
let double = x => x * 2 // 'double' is a function that transforms x into x*2
is not the same as a checking one (mostly used in filters, sort, and other kind of validating functions, usually as callback function, etc)
let isArray = arr => Array.isArray(arr) // that last one already returns boolean by itself, no need to write return (Array.isArray() etc)
Last thing to know about return is that when you write code in multiple lines, the ASI (Automatic Semicolon Insertion) will insert a ';' after return if you mistakenly press enter after writing the return word, which will break the code, therefore instead of
return
a+b;
your code will behave as
return;
a+b;
so you better write the code with parentheses as here:
return (
a + b
);
as explained in MDN website here, too.

How to get parameter of an arrow function inside another function?

I want to create a functions that returns the parameter of another function. I know I can use argument or rest operator to access parameter inside a function itself, but how can I get them outside that function?
const returnValue = (fn) => {
//How can I get the parameter of fn? Assume I know its arity.
}
For example:
const foo = 'bar'
const hello = 'world'
const returnFirstArgument = (val1, val2) => val1
const returnArgumentByPosition = (fn, num) => {
//Take fn as input, return one of its parameter by number
}
const returnSecondArgument = returnArgumentByPosition(returnFirstArgument(foo, hello), 1) //Expect it returns 'world'
What you want isn't possible to do without modifying how returnFirstArgument behaves. Take for example the below piece of code:
const x = 1 + 2;
console.log(x); // 3
Before a value is assigned to x, the expression 1 + 2 needs to be evaluated to a value. In this case 1 + 2 gets evaluated to 3, so x gets assigned to 3, that way when we print it, it prints the literal number 3 out in the console. Since it is now just a number, we can't tell how 3 was derived (it could have come from 0 + 3, 1 * 3, etc...).
Now take a similar example below:
const max = Math.max(1, 2);
console.log(max); // 2
The same idea here applies from above. First Math.max(1, 2) is evaluated to the value of 2, which is then assigned to max. Again, we have no way of telling how 2 was derived.
Now consider a function:
const add = (x, y) => x + y;
const ans = add(1 + 2, Math.max(1, 2));
console.log(ans); // 5
When we call the function, the function's arguments are first evaluated to values. The parameters within the function are then assigned to copies of these values:
const ans = add(1 + 2, Math.max(1, 2));
// ^--------^------------- both evaluate first before function is invoked
so the above function call becomes:
const ans = add(3, 2);
As a result, inside the add function, x becomes 3 and y becomes 2. Just like with the above first two examples with variables, we have no way of knowing the 3 came from the expression 1+2 and that 2 came from the function call of Math.max(1, 2).
So, relating this back to your original question. Your function call is analogous to the add function call shown above:
const returnSecondArgument = returnArgumentByPosition(returnFirstArgument(foo, hello), 1)
just like in the other examples, the arguments passed to the function can't be expressions, so they need to be evaluated first to values. returnFirstArgument(foo, hello) is evaluated to a value before the returnArgumentByPosition function is invoked. It will evaluate to the string "bar". This results in fn becoming "bar" inside of your returnArgumentByPosition. As "bar" is just a string, we again have to way of telling where it came from, and so, won't have access to the function which created it. As a result, we can't access the second argument of the function, since this information is not retained anywhere.
One approach to do what you're after is to create a recall function. The recall function is able to "save" the arguments you passed into it, and then expose them later. Put simply, it wraps your original function but is able to save the arguments and the result of calling your original function:
const recall = fn => (...args) => {
return {
args,
result: fn(...args),
}
};
const add = recall((x, y) => x + y);
const getN = ({args}, n) => {
return args[n];
}
const res = getN(add(1, 2), 1);
console.log(res);
The above approach means that add() will return an object. To get the result of calling add, you can use .result. The same idea applies to get the arguments of add(). You can use .args on the returned object. This way of saving data is fine, however, if you want a more functional approach, you can save the data as arguments to a function:
const recall = fn => (...args) => {
return selector => selector(
args, // arguments
fn(...args) // result
);
};
// Selectors
const args = args => args;
const result = (_, result) => result;
const getN = (wrapped, n) => {
return wrapped(args)[n];
}
const add = recall((x, y) => x + y);
const wrappedAns = add(1, 2);
const nth = getN(wrappedAns, 1);
console.log(nth); // the second argument
console.log(wrappedAns(result)); // result of 1 + 2
above, rather than returning an object like we were before, we're instead returning a function of the form:
return selector => selector(args, fn(...args));
here you can see that selector is a function itself which gets passed the arguments as well as the result of calling fn() (ie: your addition function). Above, I have defined two selector functions, one called args and another called result. If the selector above is the args function then it will be passed args as the first argument, which it then returns. Similarly, if the selector function above is the result function, it will get passed both the args and the result of calling fn, and will return the result the return value of fn(...args).
Tidying up the above (removing explicit returns etc) and applying it to your example we get the following:
const foo = 'bar';
const hello = 'world';
const recall = fn => (...args) => sel => sel(args, fn(...args));
const returnFirstArgument = recall((val1, val2) => val1);
const returnArgumentByPosition = (fn, num) => fn(x => x)[num];
const returnSecondArgument = returnArgumentByPosition(returnFirstArgument(foo, hello), 1);
console.log(returnSecondArgument); // world
Side note (for an approach using combinators):
In functional programming, there is a concept of combinators. Combinators are functions which can be used as a basis to form other (more useful) functions.
One combinator is the identity-function, which simply takes its first argument and returns it:
const I = x => x;
Another combinator is the K-combinator, which has the following structure:
const K = x => y => x;
You may have noticed that the first selector function args is missing an argument. This is because JavaScript doesn't require you to enter all the parameters that are passed as arguments into the function definition, instead, you can list only the ones you need. If we were to rewrite the args function so that it showed all the arguments that it takes, then it would have the following structure:
const args = (args, result) => args;
If we curry the arguments of this function, we get:
const args = args => result => args;
If you compare this function to the K-combinator above, it has the exact same shape. The K-combinator returns the first curried argument, and ignores the rest, the same applies with our args function. So, we can say that args = K.
Similarly, we can do a similar thing for the result selector shown above. First, we can curry the arguments of the results selector:
const result = _ => result => result;
Notice that this almost has the same shape as the K combinator, except that we're returning the second argument rather than the first. If we pass the identify function into the K-combinator like so K(I), we get the following:
const K = x => y => x;
K(I) returns y => I
As we know that I is x => x, we can rewrite the returned value of y => I in terms of x:
y => I
can be written as...
y => x => x;
We can then alpha-reduce (change the name of y to _ and x to result) to get _ => result => result. This now is the exact same result as the curried result function. Changing variable names like this is perfectly fine, as they still refer to the same thing once changed.
So, if we modify how selector is called in the recall function so that it is now curried, we can make use of the I and K combinators:
const I = x => x;
const K = x => y => x;
const recall = fn => (...args) => sel => sel(args)(fn(...args));
const args = K;
const result = K(I);
const getN = (fn, n) => fn(args)[n];
const add = recall((x, y) => x + y);
const addFn = add(1, 2);
const nth = getN(addFn, 1);
console.log(nth); // the second argument
console.log(addFn(result)); // result of 1 + 2

js function with n number of parenthesis

How to define a function in Javascript with n number of parenthesis. For example if we have a sum function , we should be able to call it as below
sum(2)(1)(5);
and it should return 8, where the number of parenthesis can be 1 to n.
This should be close enough
function sum(x) {  
var _b = x;
  var f = function(n) {
_b += n;
return f;
}
f.valueOf = function() {
return _b;
}
return f;
}
console.log( sum(1)(2)(3) + 1 );
Note that the best you can do still requires a trick to get a value from the function that just has to return another function (so that you can call it again).
The trick consists in defining valueOf/toString so that a value of the internal buffer is returned when necessary.
What you're asking for is not exactly possible. The problem is in that if you want to chain functions, each has to return a function.
Now you want the final call to return a number, but how could the function know when to return the final value instead of a function?
You could however pass any number of arguments to a function, and access them with arguments.
function sum(/*num1, num2, num3, ..., numN*/) {
return [].reduce.call(arguments, function(sum, num) {
return sum + num;
}, 0);
}
console.log(sum(1, 2, 3));
Or alternately, store the sum in the outer scope and never return the value.
var sum = 0;
function add(num) {
sum += num;
return add;
}
add(1)(2)(3);
console.log(sum);
In JavaScript a value cannot be both a function and a number at the same time, so you somehow need to indicate that you want to have the number after the last argument was passed to it.
One way to do this, is to let the function return the sum value when you pass it no argument (an extra pair of parentheses):
sum(2)(3)(6)()
This you can implement like this:
function sum(a) {
return b => b === undefined ? a : sum(a+b);
}
var a = sum(2)(3)(6)();
console.log(a);
An alternative, as suggested also by Wictor, is to use the returned function in way that it will coerce to a number. By defining an appropriate valueOf method you can then define what that number should be when this happens.
This can be combined with the previous method, so that you can actually choose how to get the number value:
function sum(a) {
var f = b => b === undefined ? a : sum(a+b);
f.valueOf = _ => a;
return f;
}
// method 1:
console.log(sum(2)(3)(6)());
// method 2:
console.log(+sum(2)(3)(6));
Note that to coerce to a value to a number, you can use the unitary +.
With Object.assign this can be rewritten in functional programming style:
function sum(a) {
return Object.assign(b => b === undefined ? a : sum(a+b), { valueOf: _ => a });
}
// method 1:
console.log(sum(2)(3)(6)());
// method 2:
console.log(+sum(2)(3)(6));

Calling a JavaScript function several times (ex: myFunc(1,2,3)(1,2)(2); ) [duplicate]

I trying to make next with closure:
function func(number) {
var result = number;
var res = function(num) {
return result + num;
};
return res;
}
var result = func(2)(3)(4)(5)(3);
console.log(result); // 17
I need to receive 2 + 3 + 4 + 5 + 3 = 17
But I got an error: Uncaught TypeError: number is not a function
You somehow have to signalize the end of the chain, where you are going to return the result number instead of another function. You have the choice:
make it return a function for a fixed number of times - this is the only way to use the syntax like you have it, but it's boring. Look at #PaulS' answer for that. You might make the first invocation (func(n)) provide the number for how many arguments sum is curried.
return the result under certain circumstances, like when the function is called with no arguments (#PaulS' second implementation) or with a special value (null in #AmoghTalpallikar's answer).
create a method on the function object that returns the value. valueOf() is suited well because it will be invoked when the function is casted to a primitive value. See it in action:
function func(x) {
function ret(y) {
return func(x+y);
}
ret.valueOf = function() {
return x;
};
return ret;
}
func(2) // Function
func(2).valueOf() // 2
func(2)(3) // Function
func(2)(3).valueOf() // 5
func(2)(3)(4)(5)(3) // Function
func(2)(3)(4)(5)(3)+0 // 17
You're misusing your functions.
func(2) returns the res function.
Calling that function with (3) returns the number 5 (via return result + num).
5 is not a function, so (4) gives an error.
Well, the (2)(3) part is correct. Calling func(2) is going to return you res, which is a function. But then, calling (3) is going to return you the result of res, which is a number. So the problem comes when you try to call (4).
For what you're trying to do, I don't see how Javascript would predict that you're at the end of the chain, and decide to return a number instead of a function. Maybe you could somehow return a function that has a "result" property using object properties, but mostly I'm just curious about why you're trying to do things this way. Obviously, for your specific example, the easiest way would just be adding the numbers together, but I'm guessing you're going a bit further with something.
If you want to keep invoking it, you need to keep returning a function until you want your answer. e.g. for 5 invocations
function func(number) {
var result = number,
iteration = 0,
fn = function (num) {
result += num;
if (++iteration < 4) return fn;
return result;
};
return fn;
}
func(2)(3)(4)(5)(3); // 17
You could also do something for more lengths that works like this
function func(number) {
var result = number,
fn = function () {
var i;
for (i = 0; i < arguments.length; ++i)
result += arguments[i];
if (i !== 0) return fn;
return result;
};
return fn;
}
func(2)(3, 4, 5)(3)(); // 17
I flagged this as a duplicate, but since this alternative is also missing from that question I'll add it here. If I understand correctly why you would think this is interesting (having an arbitrary function that is applied sequentially to a list of values, accumulating the result), you should also look into reduce:
function sum(a, b) {
return a + b;
}
a = [2, 3, 4, 5, 3];
b = a.reduce(sum);
Another solution could be just calling the function without params in order to get the result but if you call it with params it adds to the sum.
function add() {
var sum = 0;
var closure = function() {
sum = Array.prototype.slice.call(arguments).reduce(function(total, num) {
return total + num;
}, sum);
return arguments.length ? closure : sum;
};
return closure.apply(null, arguments);
}
console.log(add(1, 2, 7)(5)(4)(2, 3)(3.14, 2.86)); // function(){}
console.log(add(1, 2, 7)(5)(4)(2, 3)(3.14, 2.86)()); // 30;
We can make light work of it using a couple helper functions identity and sumk.
sumk uses a continuation to keep a stack of the pending add computations and unwinds the stack with 0 whenever the first () is called.
const identity = x => x
const sumk = (x,k) =>
x === undefined ? k(0) : y => sumk(y, next => k(x + next))
const sum = x => sumk(x, identity)
console.log(sum()) // 0
console.log(sum(1)()) // 1
console.log(sum(1)(2)()) // 3
console.log(sum(1)(2)(3)()) // 6
console.log(sum(1)(2)(3)(4)()) // 10
console.log(sum(1)(2)(3)(4)(5)()) // 15

Closure in JavaScript - whats wrong?

I trying to make next with closure:
function func(number) {
var result = number;
var res = function(num) {
return result + num;
};
return res;
}
var result = func(2)(3)(4)(5)(3);
console.log(result); // 17
I need to receive 2 + 3 + 4 + 5 + 3 = 17
But I got an error: Uncaught TypeError: number is not a function
You somehow have to signalize the end of the chain, where you are going to return the result number instead of another function. You have the choice:
make it return a function for a fixed number of times - this is the only way to use the syntax like you have it, but it's boring. Look at #PaulS' answer for that. You might make the first invocation (func(n)) provide the number for how many arguments sum is curried.
return the result under certain circumstances, like when the function is called with no arguments (#PaulS' second implementation) or with a special value (null in #AmoghTalpallikar's answer).
create a method on the function object that returns the value. valueOf() is suited well because it will be invoked when the function is casted to a primitive value. See it in action:
function func(x) {
function ret(y) {
return func(x+y);
}
ret.valueOf = function() {
return x;
};
return ret;
}
func(2) // Function
func(2).valueOf() // 2
func(2)(3) // Function
func(2)(3).valueOf() // 5
func(2)(3)(4)(5)(3) // Function
func(2)(3)(4)(5)(3)+0 // 17
You're misusing your functions.
func(2) returns the res function.
Calling that function with (3) returns the number 5 (via return result + num).
5 is not a function, so (4) gives an error.
Well, the (2)(3) part is correct. Calling func(2) is going to return you res, which is a function. But then, calling (3) is going to return you the result of res, which is a number. So the problem comes when you try to call (4).
For what you're trying to do, I don't see how Javascript would predict that you're at the end of the chain, and decide to return a number instead of a function. Maybe you could somehow return a function that has a "result" property using object properties, but mostly I'm just curious about why you're trying to do things this way. Obviously, for your specific example, the easiest way would just be adding the numbers together, but I'm guessing you're going a bit further with something.
If you want to keep invoking it, you need to keep returning a function until you want your answer. e.g. for 5 invocations
function func(number) {
var result = number,
iteration = 0,
fn = function (num) {
result += num;
if (++iteration < 4) return fn;
return result;
};
return fn;
}
func(2)(3)(4)(5)(3); // 17
You could also do something for more lengths that works like this
function func(number) {
var result = number,
fn = function () {
var i;
for (i = 0; i < arguments.length; ++i)
result += arguments[i];
if (i !== 0) return fn;
return result;
};
return fn;
}
func(2)(3, 4, 5)(3)(); // 17
I flagged this as a duplicate, but since this alternative is also missing from that question I'll add it here. If I understand correctly why you would think this is interesting (having an arbitrary function that is applied sequentially to a list of values, accumulating the result), you should also look into reduce:
function sum(a, b) {
return a + b;
}
a = [2, 3, 4, 5, 3];
b = a.reduce(sum);
Another solution could be just calling the function without params in order to get the result but if you call it with params it adds to the sum.
function add() {
var sum = 0;
var closure = function() {
sum = Array.prototype.slice.call(arguments).reduce(function(total, num) {
return total + num;
}, sum);
return arguments.length ? closure : sum;
};
return closure.apply(null, arguments);
}
console.log(add(1, 2, 7)(5)(4)(2, 3)(3.14, 2.86)); // function(){}
console.log(add(1, 2, 7)(5)(4)(2, 3)(3.14, 2.86)()); // 30;
We can make light work of it using a couple helper functions identity and sumk.
sumk uses a continuation to keep a stack of the pending add computations and unwinds the stack with 0 whenever the first () is called.
const identity = x => x
const sumk = (x,k) =>
x === undefined ? k(0) : y => sumk(y, next => k(x + next))
const sum = x => sumk(x, identity)
console.log(sum()) // 0
console.log(sum(1)()) // 1
console.log(sum(1)(2)()) // 3
console.log(sum(1)(2)(3)()) // 6
console.log(sum(1)(2)(3)(4)()) // 10
console.log(sum(1)(2)(3)(4)(5)()) // 15

Categories