0

I am learning curry function in javascript. And a question occurs to me.

// how to implement the add function in the below.

add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;

I've known the implemented code

function add() {
var _args = Array.prototype.slice.call(arguments);
var _adder = function () {
    _args.push(...arguments);
    return _adder;
};
_adder.toString = function () {
    return _args.reduce(function (a, b) {
        return a + b;
    });
}
return _adder;
}
console.log(add(1)(2)(3)(4)(5))    // function 
console.log(add(1)(2)(3))          // function
console.log(add(1, 2, 3)(4))       // function

console.log(add(1)(2)(3)(4)(5) == 15)  // true 
console.log(add(1)(2)(3) == 6)         // true
console.log(add(1, 2, 3)(4) == 10)     // true

console.log(add(1)(2)(3)(4)(5) === 15)  // false
console.log(add(1)(2)(3) === 6)         // false
console.log(add(1, 2, 3)(4) === 10)     // false

I know how the implemented code works. But I am very curious about the question. From my view, " add(1)(2)(3) = 6; " means that after executing the expression "add(1)(2)(3)", it should return a value which is fully equals to Number 6. But from this question and its implement codes, I may have a misunderstanding about the question. SO, what does the question REALLY mean? This question is often asked by the interviewer.

palaѕн
  • 72,112
  • 17
  • 116
  • 136
quan lili
  • 109
  • 6
  • On my Chrome browser the first three cases return the numbers 15, 6 and 10 and not "function". – Carsten Massmann Jun 01 '20 at 04:48
  • Two more variants: `console.log(typeof add(1)(2)(3)(4)(5))` returns "function" and `console.log(add(1)(2)(3)(4)(5) +0 === 15)` returns "true". – Carsten Massmann Jun 01 '20 at 05:10
  • oh. That's queer indeed. I use chrome too. Its version is 83. – quan lili Jun 01 '20 at 06:37
  • I just test the code in my safari(version 13.1) and firefox(version 76) browser. In firefox, the first three cases return functions. And in the safari, it returns the number 15, 6 and 10. But when I want to see the type of the "add(1)(2)(3)(4)(5)", the safari just give me "function". – quan lili Jun 01 '20 at 06:44

1 Answers1

1

This comes down to the JavaScript operators.

= does assignment.

=== does a normal equality comparison. A function never equals a number.

== does troublesome type conversions on the two values, then an equality test. It's usually better to avoid it. In this case, those type conversions can convert your curried function to a string, which might call your toString method if its complicated rules make it coerce the first arg to a string, which runs your curried function, and it converts the other argument to a string, and the two strings are equal.

This kind of automatic-conversion-and-hope-for-the-best test is easy to do the wrong thing. Examples:

  • console.log(add(10)(-10) == '') --> true
  • console.log(add(10)(20) == 30) --> true
  • console.log(add(10)(20) == ' 30 ') --> true
  • console.log(add(10)(20) == 036) --> true
  • console.log(add(10)(20) == ' 036 ') --> false
  • console.log(add(10)(20) == ' 36 ') --> false
  • console.log(add(2)(-2) == []) -> false
  • console.log(0 == []) --> true

Also see https://stackoverflow.com/a/359509/1682419

Jerry101
  • 12,157
  • 5
  • 44
  • 63
  • @quan The important point here is `.toString()` is the troublesome method. `console.log` is calling `.toString()` which is converting the integer. Here's a sweet resource on currying https://javascript.info/currying-partials#advanced-curry-implementation – djthoms Jun 01 '20 at 04:19
  • @djthoms if the code was `console.log(add(1)(2)(3)(4)(5))`, then indeed `console.log` would be calling `.toString()`. But in this case, the code amounts to `console.log(… == 15)` so JavaScript runs the `==` operator before converting _that_ result to a string. – Jerry101 Jun 01 '20 at 04:36
  • I know the implement code. And the method of toString and valueOf will be called in order when an Object is forced to convert to the primitive type of String. Thank you after all. I just cannot figure out the actual meaning of the question. – quan lili Jun 01 '20 at 06:48
  • @quanlili If the interviewer's question is "how to understand this?", I take that to mean "how to predict the result?", "what happens if you make small changes to it", and "when or why would you use this or avoid using this in writing software?" I wouldn't use the self-currying function in JavaScript because its return value interacts with other operations in a hard-to-predict way. When engineering software, we want code that's easy to predict, easy to modify, reliable across browsers. – Jerry101 Jun 01 '20 at 15:42
  • It's bad idea to write such code in an actual project. But the interview is the interview. – quan lili Jun 02 '20 at 01:57