A friend of mine challenged me to write a function that works with both of these scenarios
add(2,4) // 6
add(2)(4) // 6
My instinct was the write an add() function that returns itself but I'm not sure I'm heading in the right direction. This failed.
function add(num1, num2){
if (num1 && num2){
return num1 + num2;
} else {
return this;
}
}
alert(add(1)(2));
So I started reading up on functions that return other functions or return themselves.
http://davidwalsh.name/javascript-functions
JavaScript: self-calling function returns a closure. What is it for?
JavaScript: self-calling function returns a closure. What is it for?
I am going to keep trying, but if someone out there has a slick solution, I'd love to see it!
I wrote a curried function whose valueOf() method and function context (this) are bound with the sum no matter how many arguments are passed each time.
/* add function */
let add = function add(...args) {
const sum = args.reduce((acc, val) => acc + val, this);
const chain = add.bind(sum);
chain.valueOf = () => sum;
return chain;
}.bind(0);
/* tests */
console.log('add(1, 2) = ' + add(1, 2));
console.log('add(1)(2) = ' + add(1)(2));
/* even cooler stuff */
console.log('add(1, 2)(3) = ' + add(1, 2)(3));
console.log('add(1, 2, 3)(4, 5)(6) = ' + add(1, 2, 3)(4, 5)(6));
/* retains expected state */
let add7 = add(7);
console.log('let add7 = add(7)');
console.log('add7(3) = ' + add7(3));
console.log('add7(8) = ' + add7(8));
The reason why both mechanisms are required is because the body of add() must use the called function's bound context in order to access the sum of the intermediate partial application, and the call site must use the valueOf() member (either implicitly or explicitly) in order to access the final sum.
There is an article on Dr.Dobs Journal about "Currying and Partial Functions in JavaScript" which describes exactly this problem.
One solution found in this article is:
// a curried add
// accepts partial list of arguments
function add(x, y) {
if (typeof y === "undefined") { // partial
return function (y) {
return x + y;
};
}
// full application
return x + y;
}
function add(num1, num2){
if (num1 && num2) {
return num1 + num2;
} else if (num1) {
return function(num2){return num1 + num2;};
}
return 0;
}
The concept that you're looking for is called currying and it has to do with function transformation and partial function application. This is useful for when you find yourself calling the same function over and over with mostly the same arguments.
An example of implementing add(2)(6) via currying would look something like this...
function add(x,y) {
if (typeof y === 'undefined') {
return function(y) {
return x + y;
}
}
}
add(2)(4); // => 6
Additionally, you could do something like this...
var add6 = add(6);
typeof add6; // => 'function'
add6(4); // => 10
var add = function(){
// the function was called with 2 arguments
if(arguments.length > 1)
arguments.callee.first_argument = arguments[0];
// if the first argument was initialized
if(arguments.callee.first_argument){
var result = arguments.callee.first_argument + arguments[arguments.length - 1];
arguments.callee.first_argument = 0;
return result;
}else{// if the function was called with one argument only then we need to memorize it and return the same function handler
arguments.callee.first_argument = arguments.callee.first_argument || arguments[0];
return arguments.callee;
}
}
console.log(add(2)(4));
console.log(add(2, 4));
An extended solution which depends on the environment:
function add(){
add.toString = function(){
var answer = 0;
for(i = 0; i < add.params.length; i++)
answer += add.params[i];
return answer;
};
add.params = add.params || [];
for(var i = 0; i < arguments.length; i++)
add.params.push(arguments[i])
return add;
}
console.log(add(2)(4)(6)(8))
console.log(add(2, 4, 6, 8));
We can use the concept of closures which is provided by Javascript.
Code snippet:
function add(a,b){
if(b !== undefined){
console.log(a + b);
return;
}
return function(b){
console.log(a + b);
}
}
add(2,3);
add(2)(3);
In general you need to have an agreement whether the function should return a function (for calling with more arguments) or the end result. Imagine the add function would have to work like this as well:
add(1, 2, 3)(4, 5) // -> 15
...then it becomes ambiguous, because you might want to call again:
add(1, 2, 3)(4, 5)(6) // -> 21
...and so add(1, 2, 3)(4, 5) should have returned a function, and not 15.
You could for instance agree that you have to call the function again, but without arguments, in order to get the numeric result:
function add(...args) {
if (args.length === 0) return 0;
let sum = args.reduce((a, b) => a+b, 0);
return (...args) => args.length ? add(sum, ...args) : sum;
}
console.log(add()); // 0
console.log(add(1,2,3)()); // 6
console.log(add(1,2,3)(4,5)()); // 15
console.log(add(1,2,3)(4,5)(6)()); // 21
One may think that he/she has to invoke the same function two times, but if you think deeply you will realize that the problem is pretty straight forward, you have to invoke the add function one time then you need to invoke what ever the add function returns.
function add(a){
return function(b){
return a+b;
}
}
console.log(add(20)(20));
//output: 40
you can return function as many as time you want. suppose for y = mx+c
const y= function (m){
return function(x){
return function (c){
return m*x+c
}
}
}
console.log(y(10)(5)(10));
//out put: 60
While learning with FreeCodeCamp I'm faced with a question about currying.
The solution was this:
function add(x) {
// Add your code below this line
return function(y) {
return function(z) {
return x + y + z;
}
}
}
add(10)(20)(30);
However, I'm confused as to why the return statements here aren't terminating the execution of the function?
I was under the impression that as soon as you use a return statement, that line would be executed and everything beyond that would be ignored.
It ends only the own function. The returned function isn't called yet.
function add(x) {
return function(y) { // \
return function(z) { // |
return x + y + z; // | part of the returned function
}; // |
}; // /
}
add(10)(20)(30);
Yes using return does end the functions execution, but the returned value is a function itself, that then gets called directly, the next function gets executed, ended with returning another function, that then gets called directly again and produces the result.
add(10)(20)(30);
// evaluted to:
function(x) {
return function(y) {
return function(z) {
return x + y + z;
};
};
}(10)(20)(30)
// evaluated to:
function(y) { // x = 10 through closure
return function(z) {
return x + y + z;
};
}(20)(30);
// evaluated to
function(z) { // x = 10, y = 20 through closure
return x + y + z;
}(30)
// evaluated to
60
Each time it is returning a new function, its being executed.
You would be right if one function had multiple return statements, but in this case, there are multiple functions (each with their own return statement). Two of the functions just happen to return another function.
I have two file:
//------------a.js--------------
function a(){
return '1'
}
var testCase = {
func(){
return a()
}
}
module.exports = testCase
//------------b.js--------------
var testCase = require('./a.js')
//Can I get closure parameters(function a) that not modify a.js?
Is there a way to get closure parameters In JavaScript? Thank You!
If you mean to return the list of parameters from a closure like get x and y from closure run(x, y) {} which is inside function walk() {} then the below code might help.
function walk() {
function run(x, y) {
return x + y;
}
return run;
}
var fun = walk();
fun.getParameters = function () {
var functionText = this.prototype.constructor.toString();
return functionText
.substring(functionText.indexOf('(') + 1, functionText.indexOf(')'))
.split(',')
.map(x => x.trim());
};
console.log(fun.getParameters());
I'm trying to pass a function with two arguments as an argument to another function (sort of callbacks). I have one function that is unchangeble ("F"), and another that's a wrapper to the former one, and which I can code the way I like ("G"). I tried to simplify the code as much as possible, leaving just the important parts of it:
"use strict"
// this function can't be changed in any way
var F = function (a, b)
{
return new G(function (success, error)
{
var sum = a + b;
if (sum > 0)
{
// EXCEPTION: point of failure, since we can't reach G.success
success(sum);
}
else
{
// of course we'd fail here too
error(sum);
}
});
};
var G = function (f)
{
this.success = function (result)
{
console.log("The sum is positive: " + result);
}
this.error = function (result)
{
console.log("The sum is negative: " + result);
}
return f();
};
var result = F(10, 5);
It is possible to code in javascript like the following:
var foo = function(n) { //magic codes };
var bar = foo(2);
bar + 2 // result: 4
bar(2) // result: 4
bar(2)(2) // result: 6
A variable can only hold one value. That value can be a function.
An object can have a toString() method which could be hacked to get close to what you are trying to do.
function myFactory(value) {
function myFunction(add) {
return myFactory(value + add);
}
myFunction.toString = function() {
return value;
};
return myFunction;
}
var bar = myFactory(2);
console.log(bar + 2);
console.log(bar(2));
console.log(bar(2)(2));
This is, of course, horrible.
Currying can be done in Javascript, by returning a function.
By default variables can either be values (literal, or results of functions), or function declarations.
function add(number) {
return function(number2) {
return number + number2;
}
}
console.log(add(5)(6));
There are ways to achieve what you described bar + 2, but that's unconventional, and in my opinion, you shouldn't use them in Javascript.
I got inspired by Quetin's answer and found the valueOf property
var foo = function(n) {
var fn = function(x) {
return foo(n + x);
};
fn.valueOf = function() {
return n;
};
return fn;
}
var bar = foo(2);
console.log(bar + 2 === 4, bar);
console.log(bar(2) === 4, bar(2));
console.log(bar(2)(2) === 6, bar(2)(2));
I admit the log results does come out strange but it works as intended.