Skip to content

Instantly share code, notes, and snippets.

@sagirk
Last active July 2, 2018 04:52
Show Gist options
  • Save sagirk/27ce0a34b4f73b7996fcefa142b51cc1 to your computer and use it in GitHub Desktop.
Save sagirk/27ce0a34b4f73b7996fcefa142b51cc1 to your computer and use it in GitHub Desktop.
An `add(...)` function that keeps going forever
/**
* Second Implementation
*
* 1. The function `bind(a, b)` will return the calling function with the first
* argument as context for, and the rest of the arguments as arguments to the
* returned function.
*
* 2. In addition to the bind call, the `valueOf` property on every function
* type is the function that is called whenever the JS runtime needs to typecast
* that function to a primitive type. The type of variable actually being
* returned by the add function is a function, however when this function is
* typecasted (by adding it to another number or string), the `valueOf` function
* is called, and the result of that function is then used as the value of the
* function.
*
* In this implementation, typecasting is done using the unary plus (+)
* operator. It precedes its operand and evaluates to its operand but attempts
* to convert it into a number, if it isn't already.
*
* Unary plus is the fastest and preferred way of converting something into a
* number, because it does not perform any other operations on the number.
* — MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators)
*/
function add() {
var sum = 0;
for (var i in arguments) {
sum += arguments[i];
}
var addAndRepeat = add.bind(null, sum);
addAndRepeat.valueOf = function valueOf() {
return sum;
};
return addAndRepeat;
}
console.log(+add()); //........................................ 0
console.log(+add(1)); //....................................... 1
console.log(+add(1, 2)); //.................................... 3
console.log(+add(1)(2)); //.................................... 3
console.log(+add(1, 2)(3)); //................................. 6
console.log(+add()()(1, 2)()(3)); //........................... 6
console.log(+add(1, 2)(3)(4, 5)(6)); //........................ 21
console.log(+add(1)(2)(3)(4)(5)(6)(7)(8)); //.................. 36
/**
* First Implementation
*
* A parameter-less invocation of `add()` marks the end of operation
*/
function addUntilEmptyInvocation(x) {
var sum = 0;
sum += x;
return function addAndRepeat(y) {
if (typeof y !== 'undefined') {
sum += y;
return addAndRepeat;
} else {
return sum;
}
};
}
console.log(addUntilEmptyInvocation(1)(2)(3)(4)(5)(6)()); //... 21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment