Javascript: How to store a declared function in a variable? - javascript

I'm learning Javascript and wondering if it's possible to store a declared function in a variable to be used later?
For context,
function add(a, b) {
return a + b;
}
var addTogether = _.partial(add, 1);
doSomething() // returns a promise that resolves to a 2
.then(addTogether); // expect to return 3
Is there a way to achieve this?

var Add = function (a, b)
{
return a + b;
}
var result = Add (2, 3);

Absolutely. Functions ARE data in JavaScript.
var foo = function(a, b) {
return a + b;
}
Is perfectly legitimate.
function add(a, b) {
return a + b;
}
var foo = add;
console.log(foo(5,10));
console.log(add(10, 20));

You can also use ES6 syntax to store anonymous functions in constants, like so:
const add = (a, b) => a + b;
const addOne = a => add(a, 1);
console.log(add(5, 10)); // 15
console.log(addOne(5)); // 6

Related

Why does the default JS bind function works and why my polyfill for the bind returns undefined?

I am trying to write the polyfill for the js bind function over a multiply function. The js bind function is giving the correct answer 8 but my polyfill is giving undefined. The main multiply function is returning all the params correctly though.
Function.prototype.myBind = function (...args) {
let obj = this;
let params = args.slice(1);
return function (...param2) {
obj.apply(args[0], [...params, ...param2]);
};
};
let mul = (a, b) => {
console.log(13, a, b, a * b);
return a * b;
};
let mulFour = mul.bind(this, 4);
let myMulFour = mul.myBind(this, 4);
console.log(mulFour(2));
console.log(myMulFour(2));
CertainPerformance was correct, needed to return the obj.apply(args[0], [...params, ...param2]); again.
The polyfill would go like this:
Function.prototype.myBind = function (...args) {
let obj = this;
let params = args.slice(1);
return function (...param2) {
return obj.apply(args[0], [...params, ...param2]);
};
};

Finding the sum of a curry function?

var curry = function (func) {
return function (a) {
return function (b) {
return function (c) {
return function (d) {
return function (e) {
return func (a, b, c, d, e);
}
}
}
}
}
}
var getSum=curry(a+b+c+d+e);
console.log(getSum(15)(20)(25)(30)(35));
This is my code so far, but it's saying a is not defined and I'm not sure how to fix it. If I do this with Math.max it works, how can I achieve the same thing but with a sum instead of max?
By defining a function that sums its arguments, just like Math.max finds the max of its arguments:
const curry = function (func) {
return function (a) {
return function (b) {
return function (c) {
return function (d) {
return function (e) {
return func (a, b, c, d, e);
};
};
};
};
};
};
const getSum = (...args) => {
return args.reduce((sum, value) => sum + value, 0);
};
console.log(curry(getSum)(15)(20)(25)(30)(35));
Curry is expecting a function with your decleration
var curry = function (func) {...}
You should be calling it with a function. However you're attempting to resolving some variables and add them then just pass the number. What you have here is a Higher Order Function, or a Function which takes a Function and returns a Function.
var getSum=curry(a+b+c+d+e); // not passing a function
Your code however is attempting to do the following:
var temp = a+b+c+d+e;
var getSum=curry(temp);
The problem is that now it's attempting to find a global a, b, c, d, and e variable, to sum them, and then pass that to curry... which fails as soon as it tries to find a global a. What you want to pass is a function.
var getSum = curry((...arg) => args.reduce((acc, value) => acc + value));
This is a function that takes a variable amount of arguments, so when you pass it to curry it will return a function(a internal to curry scope), which when called will return a function(b to a scope) which will return a fun.... so on and so forth until it finally calls the last time and sums them all after the last call.
Another more advanced version of an automatic curry function with examples from 30 Seconds of Code
const curry = (fn, arity = fn.length, ...args) =>
arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);
curry(Math.pow)(2)(10); // 1024
curry(Math.min, 3)(10)(50)(2); // 2
Other versions of Curry exist in other places like RamdaJS, but you get the idea. It's a higher order function that continuously returns functions until you've supplied enough arguments to satisfy it's arity(how many arguments it wants).
You need to supply a function for the five parameters and take the function for the first call of curry.
var curry = function(func) {
return function(a) {
return function(b) {
return function(c) {
return function(d) {
return function(e) {
return func(a, b, c, d, e);
}
}
}
}
}
}
var getSum = function (a, b, c, d, e) { return a + b + c + d + e; };
console.log(curry(getSum)(15)(20)(25)(30)(35));
A dynamic approach without binding.
var curry = fn => {
const
curried = p => (...args) => {
p = [...p, ...args];
return p.length < fn.length
? curried(p)
: fn(...p);
};
return curried([]);
},
getSum = (a, b, c, d, e) => a + b + c + d + e;
console.log(curry(getSum)(15)(20)(25)(30)(35));
var add = curry((a, b, c, d) => a + b + c + d),
add1 = add(1),
add2 = add(2)(3)(4);
console.log(add1() === 10); // false
A dynamic approach for curry function. Here What I have done is curry function takes the function to be curried func returns a new function temp.
Inside temp we check if length of arguments of temp is less than the number of arguments required for the original function func.
If it is less we return temp again with the arguments received, else call the original function func with all the arguments
var getSum = function (a, b, c, d, e) { return a + b + c + d + e; };
function curry(func){
return function temp(...args) {
if (args.length < func.length) {
return temp.bind(null, ...args)
}
return func(...args)
}
}
console.log(curry(getSum)(15)(20)(25)(30)(35));

Javascript: return multiple values from different functions

I am trying to return multiple values from different functions.
The starting point is a bidimensional array. An example of the code is:
var items = [[0,1],[1,2],[0,2]];
var a;
var b;
function first() {
a = items[Math.floor(Math.random() * items.length)];
return a;
}
function second() {
b = a[Math.floor(Math.random() * 2)];
return b;
}
function third (){
first();
second();
}
third();
If I write the code outside the functions, everything works fine. When I use functions and replace return with console.log, it works. If I use functions and return (as in the code reported above), it gives me undefined. I didn't find solutions. Why the code isn't working?
Thanks in advance
If you are declaring variable a and b outside function(like in your code) than there is no need to return the values. a and b will get defined.
But if you are not declaring it outside, then store the return values in array variable.
var items = [[0,1],[1,2],[0,2]];
function first() {
a = items[Math.floor(Math.random() * items.length)];
return a;
}
function second() {
b = a[Math.floor(Math.random() * 2)];
return b;
}
function third (){
var a = first();
var b = second();
var arr = [];
arr.push(a);
arr.push(b);
return arr
}
var t = third();
console.log(t[0], t[1]);
If you want third to return values, add a return in it.
function third (){
var a = [];
a.push(first())
a.push(second())
return a;
}
Maybe you want something like
function third (){
return {a: first(), b: second()};
}
then
var t = third()
console.log(t.a, t.b)
or if you're running on ES6
var {a,b} = third()
console.log(a, b)
see Destructuring assignment for further details

Currying in javascript for function with n parameters

If f :: (a, b) -> c, we can define curry(f) as below:
curry(f) :: ((a, b) -> c) -> a -> b -> c
const curry = f => a => b => f(a, b);
const sum = curry((num1, num2) => num1 + num2);
console.log(sum(2)(3)); //5
How do we implement generic curry function that takes a function with n parameters?
If I understand correctly, I think this is the way to go using ES6:
const curry = f => {
const nargs = f.length;
const vargs = [];
const curried = (...args) => vargs.push(...args) >= nargs
? f(...vargs.slice(0, nargs))
: curried;
return curried;
};
const fn2 = curry((a, b) => a + b);
const fn3 = curry((a, b, c) => a * (b + c));
const fn4 = curry((a, b, c, d) => Math.pow(a, b * (c + d)));
console.log(fn2(1)(2)); // 1 + 2
console.log(fn3(2)(3)(4)); // 2 * (3 + 4)
console.log(fn4(2)(1, 3)(4)); // 2 ^ (1 * (3 + 4))
If you want to do this in ES5, here's a slightly more verbose method:
function curry (f) {
var nargs = f.length;
var vargs = [];
return function curried () {
return vargs.push.apply(vargs, arguments) >= nargs
? f.apply(undefined, vargs.slice(0, nargs))
: curried;
};
}
var fn2 = curry(function (a, b) {
return a + b;
});
var fn3 = curry(function (a, b, c) {
return a * (b + c);
});
var fn4 = curry(function (a, b, c, d) {
return Math.pow(a, b * (c + d));
});
console.log(fn2(1)(2)); // 1 + 2
console.log(fn3(2)(3)(4)); // 2 * (3 + 4)
console.log(fn4(2)(1, 3)(4)); // 2 ^ (1 * (3 + 4))
Caveat: I don't have a functional background, so my terminology may be a bit off.
If by "curry" you mean "create a new function that will call the original with some arguments pre-filled," the general solution in ES5 and earlier is as follows (see comments):
// Add a function to the function prototype
Object.defineProperty(Function.prototype, "curry", {
value: function() {
// Remember the original function
var f = this;
// Remember the curried arguments
var args = Array.prototype.slice.call(arguments);
// Return a new function that will do the work
return function() {
// The new function has been called: Call the original with
// the curried arguments followed by any arguments received in
// this call, passing along the current value of `this`
return f.apply(this, args.concat(Array.prototype.slice.call(arguments)));
};
}
});
// Usage:
function foo(a, b, c) {
console.log(a, b, c);
}
var f = foo.curry(1, 2);
f(3);
In ES2015+, we can use rest args instead of arguments:
// REQUIRES ES2015+ support in your browser!
// Add a function to the function prototype
Object.defineProperty(Function.prototype, "curry", {
value: function(...curriedArgs) {
// Remember the original function
let f = this;
// Return a new function that will do the work
return function(...args) {
// The new function has been called: Call the original with
// the curried arguments followed by any arguments received in
// this call, passing along the current value of `this`
return f.apply(this, curriedArgs.concat(args));
};
}
});
// Usage:
function foo(a, b, c) {
console.log(a, b, c);
}
let f = foo.curry(1, 2);
f(3);
ES6/2015
const curry = fn => function curried(cargs) {
return cargs.length >= fn.length ? fn.apply(this, cargs) : (...args) => curried([...cargs, ...args])
}([]);
const arg2 = curry((a, b) => a + b);
const arg3 = curry((a, b, c) => a * (b + c));
const arg4 = curry((a, b, c, d) => Math.pow(a, b * (c + d)));
console.log(arg2(1)(2)); // 1 + 2
console.log(arg3(2)(3)(4)); // 2 * (3 + 4)
console.log(arg4(2)(1, 3)(4)); // 2 ^ (1 * (3 + 4))
ES5
var curry = function(fn) {
var args = Array.prototype.slice.call(arguments);
if (args.length - 1 >= fn.length) return fn.apply(this, args.slice(1));
return function() {
return curry.apply(this, args.concat.apply(args, arguments));
};
};
var arg2 = curry(function(a, b) {
return a + b;
});
var arg3 = curry(function(a, b, c) {
return a * (b + c);
});
var arg4 = curry(function(a, b, c, d) {
return Math.pow(a, b * (c + d));
});
console.log(arg2(1)(2)); // 1 + 2
console.log(arg3(2)(3)(4)); // 2 * (3 + 4)
console.log(arg4(2)(1, 3)(4)); // 2 ^ (1 * (3 + 4))
There's a simple way to curry your sum function with unlimited parameters.
const add = (a) => {
const next = b => add(a + b);
next.valueOf = () => a
return next;
};
const one = add(1);
console.log(one.valueOf());
const two = one + 1;
console.log(two);
const four = two + two;
console.log(four)
const six = add(four)(two);
console.log(six.valueOf());
const eleven = six(4)(1);
console.log(eleven.valueOf());
This add function would run every time you call the curried function with another parameter. Like in the case for const six = four + two;It returns the value from two previous calls and the chain goes on and on.
Keep in mind that in order to get the primitive value we need to call .valueOf().
Below is a solution inspired by Juan Sebastián Gaitán's solution I have just extended it for below cases:
add(1, 2)(2, 3)(1, 2, 3, 4).valueOf();
add(1,2,3,4).valueOf();
add(1)(2)(3)(4)(5).valueOf();
const add = (a, ...rest) => {
a += rest.reduce((total, val) => {
return total + val;
}, 0);
const next = (...b) => add(a + b.reduce((total, val) => {
return total + val;
}, 0));
next.valueOf = () => a;
//console.log('a', a, '; next: ', next, '; rest: ', ...rest);
return next;
};
console.log(add(1, 2)(2, 3)(1, 2, 3, 4).valueOf()); //18
console.log(add(1,2,3,4).valueOf()); //10
console.log(add(1)(2)(3)(4)(5).valueOf()); //15
As the output is a function, you need valueOf(). to get the value.
the function looks little cumbersome because of .reduce() but its very simple to read.
This is a good example of recursive function and a currying function.

Accepted conventions when using 'this' with function.apply

I'm trying to implement a primitive type of Polish Notation Calculator and I'm using an object to define each operation.
Such that calling
new RPNCalculator().calculate([4, 5, '+']);
will produce an answer of 9 or
new RPNCalculator().calculate([4, 5, '+', 3, 5, '+', '*']);
will produce an answer of 72.
The code is here:
function RPNCalculator(arr) {
this.calculate = function(arr) {
var resultArr =[];
for(var i=0; i < arr.length; i++) {
if(typeof(arr[i]) == 'number') {
resultArr.push(arr[i]);
}
else {
var a = resultArr.pop();
var b = resultArr.pop();
var c = opers[arr[i]].apply(this, [a, b]);
resultArr.push(c);
}
}
return resultArr.pop();
}
var opers = {
"+": function(a, b) { return a + b; },
"-": function(a, b) { return a - b; },
"*": function(a, b) { return a * b; },
"/": function(a, b) { return a / b; }
}
}
The calculations work correctly, but what I would like to know is whether the following line
var c = opers[arr[i]].apply(this, [a, b]);
is the best way to invoke the required function contained inside the opers object based on the symbol at the current index in the array, or is there a better way to do it?
You don't really need a reference to this in your code, because the functions aren't working on any class members.
In this case, you can simply do:
var c = opers[arr[i]](a, b);
Which is a little cleaner. To be the most readable, however, I recommend this:
var operator = opers[arr[i]];
var c = operator(a, b);

Categories

Resources