1

Can someone please explain the below 'Currying' function. When I set a break point, I can see values 'b' and 'c' are undefined and returned. But how does the system get the value 7 for 'b' and 9 for 'c' in this case. Its printing the correct result for 5*7*9, ie 315 in console.

function multiply(a){
    return function (b){
        return function (c) {       
            return a*b*c ;
                }
        }
    }
var answer = multiply(5)(7)(9);
console.log(answer);
soccerway
  • 10,371
  • 19
  • 67
  • 132
  • 2
    Which part is tripping you up? You understand that the first 2 calls return functions? – Carcigenicate Aug 24 '18 at 01:26
  • While setting the break point and hover over 'b' it says 'b' undefined and system operation return to multiply ()..I got confused how system understand and need to grab the value for b in this case ? – soccerway Aug 24 '18 at 01:30
  • 2
    The break point showing undefined is probably just due to a limitation of the debugger. By the time `a*b*c` is run, the parameters `a`, `b` and `c` will all have numeric values in this case. And I don't understand what you mean by the "how system understand and need to grab..." part. `b` is just a parameter of the function. The fact that the functions are nested doesn't change that. – Carcigenicate Aug 24 '18 at 01:32
  • You can verify that they all have proper values by putting `console.log(a, b, c)` before the multiplication line. – Carcigenicate Aug 24 '18 at 01:35
  • Possible duplicate of [How do JavaScript closures work?](https://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – f-CJ Aug 24 '18 at 01:36
  • 1
    Not sure if it helps but I found arrow function syntax (`const multiply = (a) => (b) => (c) => a*b*c;`) made it a _lot_ clearer to me what I was doing. – SamVK Aug 24 '18 at 01:41
  • What line did you set the breakpoint on? – Code-Apprentice Aug 24 '18 at 01:43
  • set the break point on 'return function (b) {...' and 'return function (c) {.. – soccerway Aug 24 '18 at 01:45

3 Answers3

2

When you call multiply(5) a function is returned and that function is immediately called with multiply(5)(7) and have access to a and b, then a new function is returned and is also immediately called when multiply(5)(7)(9) and has access to a, b, and c.

The answer to why the nested functions have access to parent function parameters is closures. Please check this other question/answers about closures in javascript: link.

f-CJ
  • 4,235
  • 2
  • 30
  • 28
2

You can understand currying if you assign each intermediate result to a variable. Rewrite the function calls like this:

var x = multiply(5)
var y = x(7);
var answer = y(9);

Now it is more clear that the result of calling multiply(5) is a function. We call it with x(7) which passes the value of 7 to b. This results in another function which we call with y(9) which in turn passes the value of 9 to c and returns the final result.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
2

When you call the multiply function, the important thing is each function returns an anonymous function. It will be easier if you give them names.

function multiplyA(a){
    return function multiplyB(b){
        return function multiplyC(c) {       
            return a*b*c ;
        }
    }
}

// When you call multiplyA(5)(7)(9)
// From the first, multiplyA(5) returns multiplyB with scope with multiplyA
// just like below

const a = 5;
const multiplyB = function(b){
    return function multiplyC(c) {       
        return a*b*c ;
    }
}

// Once more call multiplyB(7)
// It also returns function named multiplyC

const a = 5;
const b = 7;
const multiplyC = function(c) {
    return a * b * c;
}

// Finally call mulitplyC(9) means 5 * 7 * 9

To understand it, closure and function scope will be helpful.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Jae Woo Woo
  • 901
  • 1
  • 8
  • 19