11

I was in an interview and I got all the questions right except for this one.

The first question leading up to it was how do you write a function for mod(3,9) so that it returns 0.

Ok, easy:

function mod(a,b){
    return b%a;
}

After that was how do you write the function mod(3)(9) so that it returns 0?

I was stumped...

Mat
  • 202,337
  • 40
  • 393
  • 406
sjmartin
  • 3,912
  • 4
  • 19
  • 32
  • 4
    Return a function. Check tutorials on higher-order functions, and currying. I think you mean `mod(3)(9)` – elclanrs May 01 '15 at 05:09
  • 3
    `mod((3)(9))` --- is not a syntactically valid JS. So it's not possible to write a function so that such a call returned `0` – zerkms May 01 '15 at 05:10
  • 1
    seems like a pretty dumb interview question – Ryan May 01 '15 at 05:11
  • right? function mod() { return 0; }. Or for other question. function mod() { return function() { return 0; }; } – Garr Godfrey May 01 '15 at 05:11
  • @elclanrs - you are correct, I had the incorrect syntax. updated question. thank you. – sjmartin May 01 '15 at 05:11
  • 3
    @self pretty fine for a junior developer to check if they know syntax basics. – zerkms May 01 '15 at 05:11
  • u need to apply closure concept here. ;) – Nielarshi May 01 '15 at 05:19
  • 1
    I just wanted to say thanks everyone. Stackoverflow is so amazing. I wish I could accept everything as an answer. Not knowing the proper terminology to search for in Google proved to be impossible to find an answer to my question only having "mod(3)(9)" as a search term. Now I know I need to study "higher-order functions" and "currying". I haven't even heard of currying before. – sjmartin May 01 '15 at 05:50

3 Answers3

18

You write a function that returns a closure.

function mod(a) {
  return function(b) {
    return b % a;
  }
}

alert(mod(3)(9));

The alert expression is short for:

var tempfun = mod(3);
alert(tempfun(9));

When you call mod(3), it returns a function that takes an argument b, and performs the modulus with the saved binding of a, which contains 3. We can then use that in the same way we'd use any other function: we can assign it to a variable and then call that as a function, or we can just call it directly by putting another pair of parentheses after it.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    I'm doing further research on currying and the examples are all too deep. I want to understand what exactly is going on here with this simple example. I get that it's a function returning a function. But I want to understand how the function being invoked works. mod(3)(9). I'm reading this as the argument being "3)(9" since parameters are supposed to be wrapped in parenthesis. I get that my thinking is wrong. so is it instead doing mod(3) first, returns function(b), and 9 is somehow passed as b? (how does that happen). then function(9) returns 9%3.... continued in next comment. – sjmartin May 01 '15 at 05:34
  • the part i'm missing in my mind is reading the syntax correctly. The argument really isn't "3)(9" so what is it? chained functions? mod(3) then mod(9)? How does the 9 turn into b? Thank you. – sjmartin May 01 '15 at 05:35
  • 2
    `var x = mod(3)(9)` is short for `var f = mod(3); var x = f(3);`. – Barmar May 01 '15 at 05:37
  • thank you, that was the part i'm missing in my head. much appreciated! – sjmartin May 01 '15 at 05:37
  • 5
    @Barmar Don't you mean `var f = mod(3); var x = f(9);`? – Drazen Bjelovuk May 01 '15 at 05:41
  • 1
    Yeah, got it right in the answer. – Barmar May 01 '15 at 05:43
11

First of all, look closely at the usage of this construction:

mod(3)(9);

You can split it into two steps:

var fn = mod(3);
fn(9);

From here is it obvious that mod(3) alone must return a new function so that later it could be invoked again. This new function needs to preserve the value passed in with the first invocation. This is the key part: you should store that value in the closure (well it's stored automatically due to nature of closures):

function mod(x) {
    return function(y) {
        return y % x;
    };
}

Here comes good illustration of the term "closure". If someone asks you (on interview, for example) you may say: closure is the function with the scope it was originally created in. So in the function above, new inner function always has internal access to the outer function parameter x.

dfsq
  • 191,768
  • 25
  • 236
  • 258
2

You can use a function that returns another function

function mod(a) {
    return function(b) {
        return b % a;
    }
}
alexreardon
  • 606
  • 5
  • 12