Skip to content

Instantly share code, notes, and snippets.

@0xadada 0xadada/sum.js
Last active Oct 21, 2018

Embed
What would you like to do?
A chained invocable, n-argument, sum function in javascript
/* This discussion was started on Reddit about a job interview question:
* Question: How would you make this work?
* add(2, 5); // 7
* add(2)(5); // 7
* url: https://www.reddit.com/r/javascript/comments/2t6riw/a_frontend_developer_interview_question_thats/cnxhnow/
*/
/**
* sum Returns the sums of N arguments.
*
* @param {Number} any number.
* @return {Number} the sum of all arguments.
*/
let sum = function() {
let args = Array.prototype.slice.call(arguments.length ? arguments : [0]);
return args.reduce((acc, i) => acc += i);
}
console.log( 'sum Tests' );
console.log( `sum() === 0`, sum() === 0 ? 'passed' : 'failed' );
console.log( `sum(1) === 1`, sum(1) === 1 ? 'passed' : 'failed' );
console.log( `sum(1,2) === 3`, sum(1,2) === 3 ? 'passed' : 'failed' );
console.log( `sum(1,2,3) === 6`, sum(1,2,3) === 6 ? 'passed' : 'failed' );
/**
* sumChainable Returns the sums of N arguments, returns an inner
* function that is chainable with the first function to produce
* additional sums.
*
* @param {Number} any number.
* @return {Function} a function, with `valueOf()` containing the
* value of the sum of all arguments.
*/
let sumChainable = function() {
let sum = [0, ...arguments].reduce((acc, i) => acc + i); // see (a)
let f = sumChainable.bind( null, sum ); // see (b)
f.valueOf = () => sum; // see (c)
return f;
}
/* (a)
* [0, ...arguments] will convert arguments to an Array
* to allow the `reduce`. It will also create an initial item
* `0` to handle the case no arguments are passed in. Thus
* making `sumChainable()` possible.
*
* (b)
* Generate a nested function that will be returned, and pass
* the sum to it. This allows the return value of the function
* to be invoked in a chain, each changed invocation passing
* the sum of its caller. Thus `sumChainable()()` is possible.
*
* (c)
* Setting the `valueOf()` function on the returned function to
* return the sum allows the comparison operator `==` to check
* the value of the function against a number. Thus making
* `sumChainable() == 0` possible.
*/
console.log( 'sumChainable tests w/ type-coercion' );
console.log( `typeof sumChainable(1) == 'function'`, typeof sumChainable(1) == `function` ? 'passed' : 'failed' );
console.log( `sumChainable() == 0`, sumChainable() == 0 ? 'passed' : 'failed' );
console.log( `sumChainable(1) == 1`, sumChainable(1) == 1 ? 'passed' : 'failed' );
console.log( `sumChainable(1) !== 1`, sumChainable(1) !== 1 ? 'passed' : 'failed' );
console.log( `x = sumChainable(1), x.valueOf() === 1`, (x = sumChainable(1), x.valueOf() === 1) ? 'passed' : 'failed' );
console.log( `sumChainable(1,2) == 3`, sumChainable(1,2) == 3 ? 'passed' : 'failed' );
console.log( `sumChainable(1,2,3) == 6`, sumChainable(1,2,3) == 6 ? 'passed' : 'failed' );
console.log( `sumChainable()() == 0`, sumChainable()() == 0 ? 'passed' : 'failed' );
console.log( `sumChainable(0)(1)`, sumChainable(0)(1) == 1 ? 'passed' : 'failed' );
console.log( `sumChainable(1,2)(3)`, sumChainable(1,2)(3) == 6 ? 'passed' : 'failed' );
console.log( `sumChainable(1,2,3)(4)(5)`, sumChainable(1,2,3)(4)(5) == 15 ? 'passed' : 'failed' );
console.log( `sumChainable(1,2,3)(4,5)(6)`, sumChainable(1,2,3)(4,5)(6) == 21 ? 'passed' : 'failed' );
// these tests are failing since the return value is a function, not a number
console.log( 'sumChainable no-coercion Tests' );
console.log( sumChainable() === 0 ? 'passed' : 'failed' );
console.log( sumChainable(1) === 1 ? 'passed' : 'failed' );
console.log( sumChainable(1,2) === 3 ? 'passed' : 'failed' );
console.log( sumChainable(1,2,3) === 6 ? 'passed' : 'failed' );
console.log( sumChainable()() === 0 ? 'passed' : 'failed' );
console.log( sumChainable(0)(1) === 1 ? 'passed' : 'failed' );
console.log( sumChainable(1,2)(3) === 6 ? 'passed' : 'failed' );
console.log( sumChainable(1,2,3)(4)(5) === 15 ? 'passed' : 'failed' );
// Can you get these failing tests to pass?
// if so, tweet at me @0xADADA
@0xadada

This comment has been minimized.

Copy link
Owner Author

0xadada commented Jan 22, 2015

If only you could return a callable number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.