Interview Question Journey - Currying, Closures, Type Coercion, oh my 😱
Tags: javascript, function, typecoercion, interview
Published: 2019-06-14 12:18:58

---
title: Interview Question Journey - Currying, Closures, Type Coercion, oh my 😱
published: true
description: Interview journey in Javascript from a simple question to a tough one
tags: javascript, function, type coercion, interview
cover_image: https://thepracticaldev.s3.amazonaws.com/i/rum3ipxalp4c93rqxsip.png
---

This post is based on the true story with minor changes for readability.

Let's say you're on interview for frontend developer position. Interviewer asks you to write a function to add two numbers.
That's easy and you come up with
```js
function add(a, b) {
  return a + b;
}
```

Next you're asked to modify the function to the `add(1)(2)` syntax. 
Well,
```js
function add(a) {
  return function(b) {
    return a + b;
  }
}
```

More parentheses! `add(1)(2)(3)` should return 6. 
No problem:
```js
function add(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    }
  }
}
```

So far so good. Next task is to write `add` function with the requirements:
```js
+add(1)(2) // should return 3
+add(1)(2)(3) // should return 6
```
It's clear that the previous solution should be rewritten to accept any amount of parentheses. We also notice the plus sign before the `add` function which leads us to think about type coercion.
What if we always return a function from `add` and coerce it to a primitive number when necessary? JavaScript calls [valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf) method to convert a function to a primitive number.
```js
function add(a) {
  return add;
}

add.valueOf = function() {
  return 42;
}

console.log(+add(1)(2)); // 42
console.log(+add(1)(2)(3)); // 42
```
We return function `add` from the function `add` and overwrite it's `valueOf` method to return a constant number when coerced to a primitive.
We don't get the correct result yet, but the big step is made. We don't get a runtime error and are able to return a number! The next step is to correctly sum the numbers.
Somehow we should accumulate the arguments the `add` function was called with. Let's start the easiest way with counter.
```js
let counter = 0;
function add(a) {
  counter += a;
  return add;
}
add.valueOf = function() {
  return counter;
};

console.log('Should be 3', +add(1)(2)); // 3
console.log('Should be 6', +add(1)(2)(3)); // 9
```
The first result is correct, but the second is wrong, because the counter was not resetted after the first coercion. Let's fix this.
```js
let counter = 0;
function add(a) {
  counter += a;
  return add;
}
add.valueOf = function() {
  let temp = counter;
  counter = 0;
  return temp;
};

console.clear();
console.log('Should be 3', +add(1)(2)); // 3
console.log('Should be 6', +add(1)(2)(3)); // 6
```
Great! Now everything works as expected! But the code isn't great, we can do better. Let's refactor 🛠
```js
function add(a) {
  let counter = a;
  function inner(b) {
    counter += b;
    return inner;
  }
  inner.valueOf = () => counter;
  return inner;
}

console.log('Should be 3', +add(1)(2)); // 3
console.log('Should be 6', +add(1)(2)(3)); // 6
```
Awesome! ✨ The result is correct and the code is nice. We created function `inner` inside the `add` and return it. The `counter` variable is in closure and there is no need to reset it like in the previous example.
Now it's possible to write expressions like this:
```js
let result = add(1)(2) + add(1)(2)(3) + add(1)(2)(3)(4) + add(1)(2)(3)(4)(5);
console.log(result); // 34
```
And get the correct result.

What do you think about such tasks on interviews? What questions were you asked on an interview? Please share in the comments!