While learning with FreeCodeCamp I'm faced with a question about currying.
The solution was this:
function add(x) {
// Add your code below this line
return function(y) {
return function(z) {
return x + y + z;
}
}
}
add(10)(20)(30);
However, I'm confused as to why the return statements here aren't terminating the execution of the function?
I was under the impression that as soon as you use a return statement, that line would be executed and everything beyond that would be ignored.
It ends only the own function. The returned function isn't called yet.
function add(x) {
return function(y) { // \
return function(z) { // |
return x + y + z; // | part of the returned function
}; // |
}; // /
}
add(10)(20)(30);
Yes using return does end the functions execution, but the returned value is a function itself, that then gets called directly, the next function gets executed, ended with returning another function, that then gets called directly again and produces the result.
add(10)(20)(30);
// evaluted to:
function(x) {
return function(y) {
return function(z) {
return x + y + z;
};
};
}(10)(20)(30)
// evaluated to:
function(y) { // x = 10 through closure
return function(z) {
return x + y + z;
};
}(20)(30);
// evaluated to
function(z) { // x = 10, y = 20 through closure
return x + y + z;
}(30)
// evaluated to
60
Each time it is returning a new function, its being executed.
You would be right if one function had multiple return statements, but in this case, there are multiple functions (each with their own return statement). Two of the functions just happen to return another function.
Related
A friend of mine challenged me to write a function that works with both of these scenarios
add(2,4) // 6
add(2)(4) // 6
My instinct was the write an add() function that returns itself but I'm not sure I'm heading in the right direction. This failed.
function add(num1, num2){
if (num1 && num2){
return num1 + num2;
} else {
return this;
}
}
alert(add(1)(2));
So I started reading up on functions that return other functions or return themselves.
http://davidwalsh.name/javascript-functions
JavaScript: self-calling function returns a closure. What is it for?
JavaScript: self-calling function returns a closure. What is it for?
I am going to keep trying, but if someone out there has a slick solution, I'd love to see it!
I wrote a curried function whose valueOf() method and function context (this) are bound with the sum no matter how many arguments are passed each time.
/* add function */
let add = function add(...args) {
const sum = args.reduce((acc, val) => acc + val, this);
const chain = add.bind(sum);
chain.valueOf = () => sum;
return chain;
}.bind(0);
/* tests */
console.log('add(1, 2) = ' + add(1, 2));
console.log('add(1)(2) = ' + add(1)(2));
/* even cooler stuff */
console.log('add(1, 2)(3) = ' + add(1, 2)(3));
console.log('add(1, 2, 3)(4, 5)(6) = ' + add(1, 2, 3)(4, 5)(6));
/* retains expected state */
let add7 = add(7);
console.log('let add7 = add(7)');
console.log('add7(3) = ' + add7(3));
console.log('add7(8) = ' + add7(8));
The reason why both mechanisms are required is because the body of add() must use the called function's bound context in order to access the sum of the intermediate partial application, and the call site must use the valueOf() member (either implicitly or explicitly) in order to access the final sum.
There is an article on Dr.Dobs Journal about "Currying and Partial Functions in JavaScript" which describes exactly this problem.
One solution found in this article is:
// a curried add
// accepts partial list of arguments
function add(x, y) {
if (typeof y === "undefined") { // partial
return function (y) {
return x + y;
};
}
// full application
return x + y;
}
function add(num1, num2){
if (num1 && num2) {
return num1 + num2;
} else if (num1) {
return function(num2){return num1 + num2;};
}
return 0;
}
The concept that you're looking for is called currying and it has to do with function transformation and partial function application. This is useful for when you find yourself calling the same function over and over with mostly the same arguments.
An example of implementing add(2)(6) via currying would look something like this...
function add(x,y) {
if (typeof y === 'undefined') {
return function(y) {
return x + y;
}
}
}
add(2)(4); // => 6
Additionally, you could do something like this...
var add6 = add(6);
typeof add6; // => 'function'
add6(4); // => 10
var add = function(){
// the function was called with 2 arguments
if(arguments.length > 1)
arguments.callee.first_argument = arguments[0];
// if the first argument was initialized
if(arguments.callee.first_argument){
var result = arguments.callee.first_argument + arguments[arguments.length - 1];
arguments.callee.first_argument = 0;
return result;
}else{// if the function was called with one argument only then we need to memorize it and return the same function handler
arguments.callee.first_argument = arguments.callee.first_argument || arguments[0];
return arguments.callee;
}
}
console.log(add(2)(4));
console.log(add(2, 4));
An extended solution which depends on the environment:
function add(){
add.toString = function(){
var answer = 0;
for(i = 0; i < add.params.length; i++)
answer += add.params[i];
return answer;
};
add.params = add.params || [];
for(var i = 0; i < arguments.length; i++)
add.params.push(arguments[i])
return add;
}
console.log(add(2)(4)(6)(8))
console.log(add(2, 4, 6, 8));
We can use the concept of closures which is provided by Javascript.
Code snippet:
function add(a,b){
if(b !== undefined){
console.log(a + b);
return;
}
return function(b){
console.log(a + b);
}
}
add(2,3);
add(2)(3);
In general you need to have an agreement whether the function should return a function (for calling with more arguments) or the end result. Imagine the add function would have to work like this as well:
add(1, 2, 3)(4, 5) // -> 15
...then it becomes ambiguous, because you might want to call again:
add(1, 2, 3)(4, 5)(6) // -> 21
...and so add(1, 2, 3)(4, 5) should have returned a function, and not 15.
You could for instance agree that you have to call the function again, but without arguments, in order to get the numeric result:
function add(...args) {
if (args.length === 0) return 0;
let sum = args.reduce((a, b) => a+b, 0);
return (...args) => args.length ? add(sum, ...args) : sum;
}
console.log(add()); // 0
console.log(add(1,2,3)()); // 6
console.log(add(1,2,3)(4,5)()); // 15
console.log(add(1,2,3)(4,5)(6)()); // 21
One may think that he/she has to invoke the same function two times, but if you think deeply you will realize that the problem is pretty straight forward, you have to invoke the add function one time then you need to invoke what ever the add function returns.
function add(a){
return function(b){
return a+b;
}
}
console.log(add(20)(20));
//output: 40
you can return function as many as time you want. suppose for y = mx+c
const y= function (m){
return function(x){
return function (c){
return m*x+c
}
}
}
console.log(y(10)(5)(10));
//out put: 60
I have a huge business logic to be executed in both of the below functions but I struck in one issue. I know its related to closure but how to solve I am not aware of. Can you through some light.
function func1() {
var x = false;
console.log('before going inside func '+x);
func2(x);
console.log('After coming outside => '+x);
//Instead of true its displaying false
}
function func2(x)
{
x = true;
console.log('inside func => '+ x);
}
func1();
My original problem is like below
function func1() {
var x = false;
var y =1;
var z=3;
func2(x,y,z);
console.log(x,y,z);
//INSTEAD OF true,10,30; its displaying false,1,3
}
function func2(x,y,z)
{
x = true;
y=10;
z=30;
}
func1();
The x parameter of func2 is completely distinct from the x variable in func1. When you do func2(x), the value of x is passed to func2, not some kind of reference to the variable. (Some languages do that; JavaScript does not.)
To return information out of a function, use return in the function, and use the function's return value where you call it:
function func1() {
var x = false;
console.log('before ' + x);
x = func2(x); // *** Note `x =`
console.log('after ' + x);
}
function func2(x) {
return true;
}
func1();
Perhaps a better example, using the value of x in func2:
function func1() {
var a = 1;
var b = 12;
console.log('a before: ' + a);
a = func2(a);
console.log('a after: ' + a);
console.log('b before: ' + b);
b = func2(b);
console.log('b after: ' + b);
}
function func2(x) {
return x * 2;
}
func1();
If you have complex information to return, return an object with properties for the complex information (or pass in an object, and have func2 fill in properties on it, it depends on the use case [and whether you're adhering to immutability paradigms]).
Imagine you want to write a recursive function that takes an accumulator and any number of ints as arguments, and you want to return the accumulator once all arguments have been summed. I am trying to express that as follows:
function f(x, ...y) {
if (!y.length) {
return x;
}
else {
x += y.shift();
f(x, ...y);
}
}
f(0,2,4,7,8,4)
If you add a console.log(x) to the first if statement, you will see the correct answer, but when you run the function, it returns undefined, so where in the recursive chain is it getting lost? I believe my base case for this recursive function is right but I'd like some insight.
You have to return from else.
function f(x, ...y) {
if (!y.length) {
return x;
} else {
x += y.shift();
return f(x, ...y);
// ^^^^^^^
}
}
In your code, if y.length !== 0 then you are in the else block, you call f that should return a value, but you do not return that value to whatever called f.
You need to return the function to itself:
return f(x, ...y);
function f(x, ...y) {
if (!y.length) {
return x;
} else {
x += y.shift();
return f(x, ...y);
}
}
console.log(f(0, 2, 4, 7, 8, 4))
This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 5 years ago.
Can anyone explain how this code works?
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
Reference: https://mozilla.org/en/docs/Web/JavaScript/Closures
When you call your makeAdder(5), it returns the reference to a new function.
function(y) {
return x + y;
};
So add5 keeps the reference. After it when you call add5(2), you pass the 2 to the function. In it when it wants to return x + y, it starts to find the variables. Starting from x, it looks and see's that the x is not defined in it and goes to the scope in which inner function was defined ` here
function makeAdder(x) {
return function(y) {
return x + y;
};
}
It see's than x was defined here, because you call and pass x during var add5 = makeAdder(5);. After it goes to find y and finds in it's scope. And after all returns x + y.
The idea is this, every function has a reference to it's creater (where it was defined) and when it doesn't find a variable, it goes to find in it's greater and so till to global scope.
function makeAdder(x) {
return function(y) {
return x + y;
};
}
When you do var add5 = makeAdder(5); the add5 becomes a function which was returnd my makeAdder,
the add5 will be following
function(y){
return 5 + y;
}
so when you do add5(2) it will do 5 + 2 and will return 7;
makeAdder(5)
x => 5 and y is not having value so x+y => 5+0 => 5
var add5 = makeAdder(5);
add5(2);
we have created variable for the function makeadder with x => 5
so now we pass y => 2 and x => 5 so x+y => 5+2 => 7
This property of outer function variable accessible in inner function is called closure property in javascript. Also adding to that y variable is not accessible to outer function.
It is possible to code in javascript like the following:
var foo = function(n) { //magic codes };
var bar = foo(2);
bar + 2 // result: 4
bar(2) // result: 4
bar(2)(2) // result: 6
A variable can only hold one value. That value can be a function.
An object can have a toString() method which could be hacked to get close to what you are trying to do.
function myFactory(value) {
function myFunction(add) {
return myFactory(value + add);
}
myFunction.toString = function() {
return value;
};
return myFunction;
}
var bar = myFactory(2);
console.log(bar + 2);
console.log(bar(2));
console.log(bar(2)(2));
This is, of course, horrible.
Currying can be done in Javascript, by returning a function.
By default variables can either be values (literal, or results of functions), or function declarations.
function add(number) {
return function(number2) {
return number + number2;
}
}
console.log(add(5)(6));
There are ways to achieve what you described bar + 2, but that's unconventional, and in my opinion, you shouldn't use them in Javascript.
I got inspired by Quetin's answer and found the valueOf property
var foo = function(n) {
var fn = function(x) {
return foo(n + x);
};
fn.valueOf = function() {
return n;
};
return fn;
}
var bar = foo(2);
console.log(bar + 2 === 4, bar);
console.log(bar(2) === 4, bar(2));
console.log(bar(2)(2) === 6, bar(2)(2));
I admit the log results does come out strange but it works as intended.