Is there a way I can create infinite closures in JavaScript [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I was presented with question and I had no idea how to do it
add() - > returns 0
add(1)() -> returns 1
add(1)(2)() -> returns 3
add(1)(2)(3)(4)() -> 10
Basically it can go on

Here is my one line solution if you love aesthetics
const add = (val) => (val ? (arg) => (arg ? add(val + arg) : val) : 0);
console.log(add(1)(2)(3)())
For Readability:
const add = (val) => {
if (val) {
return (arg) => {
if (arg) {
return add(val + arg);
} else {
return val;
}
};
}
return 0;
};
console.log(add(1)(2)(3)())
Edit : Explaination
I'll try to explain it in a simple way
lets break it down with a example add(1)(2)(3)()
So it happens like this
add(1) is evaluated first
add(1) -> returns a function (say _add())
_add() is a closure so it has access to the val variable (with value 1) and has its own parameter args with value 2
_add(2) -> calls add() again with the result of the addition (val + args)
add(1)(2)(3)() becomes -> _add(2)(3)()
_add(2) checks if it has a parameter args and if it does then it computes val + args and returns add(val +args) else 0
_add(2)(3)() becomes -> add(3)(3)()
add(3) -> _add()
_add(3) -> val + args -> add(val+args) -> add(6)
add(3)(3)() becomes -> _add(6)()
add(6)() -> returns _add()
_add() this time no parameter so return the value
I hope I was able to explain, comment if you have any doubts, I'll try my best

You can access the arguments through the variable arguments. Read more about it here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
I'm using a basic for loop, mostly for clarity, to show case it below.
function add() {
var sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
/* Alternative loop
for (let number of arguments) {
sum += number;
} */
return sum;
}
console.log( add(1) );
console.log( add(1, 2) ); // returns 3
console.log( add(1, 2, 3, 4) ); // returns 10

I think you are looking for this.
function add(a){
func = function(b){
func.result+=b;
return func;
}
func.result = a;
return func;
}
console.log(add(2)(2).result);
Each sequential call returns the same function again. You can do it infinitely and access result as property of the returned function.

Related

JavaScript Add function called as many times as you wanted

The simplest question for that is like to write a function that could return the sum of all the parameters. How I can do that?
function add () {
}
add(1)(2)(3)(); //6
add(5)(6)(7)(8)(9)() //35
I think this is exactly what you need:
function add(value) {
return (val) => val !== undefined ? add(value + val) : value;
}
console.log(add(2)(2)()); //4
console.log(add(2)(2)(5)(5)()); //14
console.log(add(1)(1)(1)(1)(1)()); //5
console.log(add(1)(1)(0)(1)(1)()); //4
How it works
For every call it declares a function inside, in result it creates a closure(persistent scope) in every call. Function created in that way has access to its parameter + previous call parameter due to existing closure.
So if I call add(2)(3)():
add(2) - returns function with visible 2 value
add(2)(3) - calls second function with input 2 + 3 and return third function with visible value equal 5
add(2)(3)() - ends computation due to empty param and returns the value
To finish the computation pipe the last call needs to be without a value.
The basic idea is to create a closure with a variable sum that we can update, and return the sum if the value is undefined, or the the inner function:
const add = (n) => {
let sum;
const inner = (n) => n === undefined ? sum : (sum = (sum || 0) + n, inner);
return inner(n);
};
console.log(add(1)(2)(3)()); //6
console.log(add(5)(6)(7)(8)(9)()); //35
I would just use a Spread syntax like this:
function add(...values) {
return values.reduce((sum, value) => sum + value, 0)
}
console.log(add(1, 4, 34, 45, 3, 4, 5))

Javascript functional programming - Should I write functions that force currying, or use _.curry when calling instead? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Example:
Version 1:
const foo = (arg1) => {
return (arg2) => {
return (arg3) => {
return arg1 + arg2 + arg3;
}
}
}
// called as part of a pipe:
const result = pipe(bar, foo(arg1)(arg2), baz);
Version 2:
const foo = (arg1, arg2, arg3) => {
return arg1 + arg2 + arg3;
}
// called as part of a pipe:
const result = pipe(bar, _curry(foo)(arg1)(arg2), baz);
The method implementation is much cleaner and more elegant in Version 2, however the call is a little uglier. Since method calls (hopefully) appear in more than one place in the codebase, I'm trying to decide which version has less drawbacks.
I hope I don't need to explain why I want to achieve using curried functions and passing single arguments. Please approach the question from a pro-functional programming standpoint.
Thanks in advance!
You can use the arguments object of the function in case you don't know how many arguments there could be like this:
function foo() {
var sum = 0;
for(var i = 0; i < arguments.length; i++)
sum += arguments[i];
return sum;
}
console.log(foo());
console.log(foo(1, 2, 3));
console.log(foo(5, 6, 3, 7, 1, 10));
And if you want a currying that is independent of the number of arguments without forcing it using _.curry, then use this:
function foo(a) {
var sum = 0;
var _ = function(a) {
if(a === undefined)
return sum;
else {
sum += a;
return _;
}
}
return _(a);
}
console.log(foo());
console.log(foo(1)(2)());
console.log(foo(1)(2)(7)(10)(5)());

Getting NaN when trying to add numbers using recursion [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I am trying to add unknown number of arguments without a loop. here's what I have done so far.
var add = function add() {
if (!arguments.length) {
return 0;
} else {
var args = [].slice.call(arguments, 0);
console.log(args[0], arguments);
args.splice(0, 1);
return args[0] + add.apply(this, args); //needtoreadaboutapply
}
};
and this is the output I get when I call add(3,4,5).
So what am I doing wrong and how can I debug such recursive calls in browser console?
3 [3, 4, 5]
4 [4, 5]
5 [5]
NaN
You are removing one element from the argument and accessing the same. So that action will cause problem when dealing with last parameter. When you remove the last parameter the array will be [] empty, at that time if you access arg[0] that will give you undefined. undefined + number = NaN.
Try to use the removed number instead of accessing it from the array,
var add = function add() {
if (!arguments.length) {
return 0;
} else {
var args = [].slice.call(arguments, 0);
var spliced = args.splice(0, 1);
console.log(args[0], arguments);
return spliced[0] + add.apply(this, args); //needtoreadaboutapply
}
};
If you aren't stuck with using recursive functions, you might want to look into using .reduce()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
var add = function add() {
var args = [].slice.call(arguments, 0);
return args.reduce(function(sum, num) {
return sum + num;
}, 0);
};
Change return args[0]+add.apply(this,args); to return arguments[0]+ add.apply(this,args)
In the question, I made a mistake of splicing args first and then referencing args[0].

What is return in JavaScript? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
What is return in JavaScript ? And what is advantage of using return function ? I can also get 16 by doing this --
var number = function ( ok ){
confirm( 8 * ok );
}
number(2);
______________________…
So, What is the advantage of using return function ?
var timesTwo = function(number) {
return number * 2;
};
var newNumber = timesTwo (8);
confirm(newNumber);
BTW, is return used for Ex :---->
var timesTwo = function(number) {
return number * 2;
};
var newNumber = timesTwo (8);
if ( newNumber === 16 ){
confirm("success");
}
else{
confirm("failure");
}
Am i right ? because i think only function can't be used for If-Else or any other code,so return used ??
return is used so that a function can return a value to its caller. If return is not used like this, then the programmer has to use global variables to pass a computed value from a function to its caller, which is bad. Also, return is not a function.
I hope this clears out the air for you about return.
Now, about your example. You've written -
var number = function ( ok ){
confirm( 8 * ok );
}
number(2);
In the first line, you are declaring an unnamed function, and you are assigning a reference to it to the number variable. If any variable holds a reference to a function, then the function can be called by placing two first brackets after the variable. That's what you are doing at the last line.
About the second example -
var timesTwo = function(number) {
return number * 2;
};
var newNumber = timesTwo (8);
confirm(newNumber);
Here you are again creating an unnamed function and storing its reference to timesTwo. This function now returns a result, so when you call it with 8, the computed value 16 gets returned by the function and is assigned to newNumber.
About the last one -
var timesTwo = function(number) {
return number * 2;
};
var newNumber = timesTwo (8);
if ( newNumber === 16 ) {
confirm("success");
}
else {
confirm("failure");
}
You could also rewrite it as follows -
var timesTwo = function(number) {
return number * 2;
};
if ( timesTwo(8) === 16 ) {
confirm("success");
}
else {
confirm("failure");
}
Here, rather than storing the returned value in newNumber and checking its value, you are directly calling the function, whose returned value will then be checked with 16. This is another benefit that returns provide - a function's returned value can be used directly in an if condition check, without storing it first in a variable.
Functions can be used in if statements. Refer to this question:
Using function's return value in if statement

getting opposite value javascript [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have two strings: "a" and "b". How to get "b" from "a". And "a" from "b" without if? Like:
var arr = ["a", "b"];
function reverse(str){
return arr[+!arr.indexOf(str)];
}
but in more elegant way.
Many, many ways to do this.
var a = 'foo', b = 'bar',
arr = [a, b];
// dictionary object
var o = {};
o[a] = b;
o[b] = a;
function reverse(x) {
return o[x];
}
// equality with cast (+x or x|0)
function reverse(x) {
return arr[+(x === a)];
}
// or
function reverse(x) {
return arr[+(x === arr[0])];
}
If you just want to take turns between the two, you could write a generator
var reverse = (function () {
var i = 1;
return function () {
return arr[i = 1 - i];
}
}());
reverse(); // "foo"
reverse(); // "bar"
reverse(); // "foo"
You could do
return arr[(str=='a')%2]
or if you don't want to hardcode 'a'
return arr[(str==arr[0])%2]
or (using the same idea)
return arr[+(str==arr[0])]
It looks marginally cleaner than your solution but how is it better than using the ternary operator ?
Use the modulo operator.
var arr = ["a", "b"];
function reverse(str){
return arr[(arr.indexOf(str) + 1) % 2];
}
You can use char/ascii conversion:
function reverse(c) {
return String.fromCharCode(195 - c.charCodeAt(0))
}
Try it
alert(reverse('a'));
alert(reverse('b'));

Categories

Resources