JS Function With Two Parentheses and Two Params - javascript

I'm trying to understand how a function works that is run with two parentheses and two parameters. Like so:
add(10)(10); // returns 20
I know how to write one that takes two params like so:
function add(a, b) {
return a + b;
}
add(10,10); // returns 20
How could I alter that function so it could be run with one set of parameters, or two, and produce the same result?
Any help is appreciated. Literally scratching my head over this.
Thanks in advance!

How could I alter that function so it could be run with one set of parameters, or two, and produce the same result?
You can almost do that, but I'm struggling to think of a good reason to.
Here's how: You detect how many arguments your function has received and, if it's received only one, you return a function instead of a number — and have that function add in the second number if it gets called:
function add(a,b) {
if (arguments.length === 1) {
return function(b2) { // You could call this arg `b` as well if you like,
return a + b2; // it would shadow (hide, supercede) the one above
};
}
return a + b;
}
console.log(add(10, 10)); // 20
console.log(add(10)(10)); // 20
I said "almost" above because just because the add function received only one argument, that doesn't guarantee that the caller is going to call the result. They could write:
var x = add(10);
...and never call the function that x now refers to.

Welcome to the wonderful world of first order functions
In JavaScript, a function can return a function since a function is just another object. A simple implementation is something like:
function add(x){
return function addOther(y){
return x + y;
};
}
This is possible because of closures and first order functions.
This also lets you do partial application, libraries like Ramda utilize this to great extent.
var addThree = add(3)
addThree(5); // 8

To extend what both T. J. Crowder and Benjamin Gruenbaum said, libraries like Ramda (disclosure: I'm one of the authors) allow you to convert a simple function like this:
function add(a, b) {
return a + b;
}
into the style under discussion by wrapping it in a call to a curry function:
var add = R.curry(function add(a, b) {
return a + b;
});
add(3, 5); //=> 8
add(3)(5); //=> 8
var add3 = add(3);
add3(5); //=> 8
The best article I know on this subject is Hugh Jackson's Why Curry Helps. I wrote a more detailed one at Favoring Curry.
Update
Here is a version of curry somewhat simpler than the one in Ramda. It would do the above and quite a bit more, but doesn't do some of the things that Ramda does with placeholder values:
// here is a function that takes a function and returns a curried version
// of it, that is, a version that performs the sort of partial application
// you describe.
var curry = function(fn) {
// first, we detect how many arguments the function has.
var fnArity = fn.length;
var partialApply = function(args) {
// now, let's create a function that's curried
return function () {
// collect the previous args as the partial, and add the new
// ones you just received
var newArgs = (args || []).concat([].slice.call(arguments, 0));
// if we have "enough" arguments, we don't need any more partial
// application and we can call the function.
if (newArgs.length >= fnArity) {
return fn.apply(this, newArgs);
} else { // else we return a partially applied version
return partialApply(newArgs);
}
};
};
return partialApply([]); // a function is itself partially applied with 0 args
};

function add() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
function total() {
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return total;
}
total.toString = function () { return sum };
return total;
}
This will work for any no of arguments and parentheses.
https://medium.com/#imdebasispanda/super-function-with-closure-86a58a9a980b

Related

I'm trying to rewrite memoize in javascript (for underscore), can someone explain this?

I know that the purpose of memoize is to cache values so code can be run faster by not having to re-calculate the same answer everytime. My issue stems from returning a function (i think). The google chrome debugger isn't that useful for me here because everytime I try to run this memoize function, it just goes from the argus variable (on line 4 i believe) all the way down to the semi-colon. Furthermore, result always returns an empty object instead of storing a value in result.
I start by defining a function:
function add(a,b){
return a+b;
}
This is my attempt at the memoize function:
_.memoize = function(func) {
var result = {};
var flag = 0;
var argus = Array.prototype.slice.call(arguments)
return function() {
if(result[key] === arguments){
flag = 1
}
else if(flag = 0){
result[argus] = func.apply(this, argus);
}
return result[argus];
};
};
I'd call memoize by doing _.memoize(add(2,5)) but the result doesn't get stored in the result object.
Am I even close to getting this memoize function working properly? Any guidance you guys can give here would be appreciated.
The biggest point you're missing is that _.memoize is called on the function first, and it returns a new function. You are calling it on the result of a function call (which is the number 7 in this case).
In order to get it to work, you need to rearrange a few things.
Also note that it's not wise to try to use an array itself as the index to an object. One approach to get around that would be to convert the arguments array to JSON and use that as the index on the results object:
function add(a, b) {
console.log('Called add(' + a + ', ' + b + ')');
return a + b;
}
var _ = {};
_.memoize = function(func) {
var results = {};
return function() {
var args = Array.prototype.slice.call(arguments);
var key = JSON.stringify(args);
if (!(key in results)) {
results[key] = func.apply(this, args);
}
return results[key];
};
};
var madd = _.memoize(add);
console.log(madd(2, 4));
console.log(madd(9, 7));
console.log(madd(2, 4));

Make function that supports currying AND the traditional multiple parameters

Question: How would you make this work?
add(2)(5); // 7
add(2, 5); // 7
I am trying to solve the question above:
I know that the first solution uses currying and would be implemented as follows:
var add = functoin(x){
return function (y){
return x+y;
};
};
while the second is jsut your normal function:
var add = functoin(x,y){
return x+y;
};
Is there a way to make both work at the same time?
You can use a higher-order function to wrap other functions with that behaviour.
This kind of function is often called curry, and it comes with many libraries (lodash, for example).
curry returns a new function that checks whether all the expected arguments have been supplied. If they have, it calls originalFunction. If not, it returns a partially applied function,
This implementation uses Function#length to test call arity, so it works with any number of arguments.
function curry (fn) {
return function (...args) {
if (args.length >= fn.length) {
return fn.call(this, ...args)
} else {
return curry(fn.bind(this, ...args))
}
}
}
function add (x, y) {
return x + y;
}
// You can curry any function!
const curriedAdd = curry(add);
console.log(curriedAdd(1, 2)); // 3
console.log(curriedAdd(1)(2)); // 3
console.log(curriedAdd(1)); // a function
You could inspect the amount of arguments passed in and return one or the either depending on it:
function add(a, b) {
if (arguments.length == 2) {
return a + b;
}
return function(b) {
return add(a, b);
}
}
console.log(add(2)(5)); // 7
console.log(add(2, 5)); // 7

Difference between js functions by using parameters

What's the difference between:
// Example 1 sum(8,2)
console.log(sum(8,2)); // Outputs what??
// Example 2 sum(8)(2)
console.log(sum(8)(2)); // Outputs what??
function sum(x,y) {
return x+y;
}
function sum(x) {
return function(y){
return x+y;
}
}
Why is one used over the other and why?
What you are trying to do is called Function Currying
Try this:
function sum(x) {
return function(y) { return x + y; }
};
var sumWith4 = sum(4);
var finalVal = sumWith4(5);
finalVal = sumWith4(8);
One of the advantages is that it helps in reusing abstract function. For example in the above example I can reuse sumWith4 to add 4 to any number with out calling sum(4,5) explicitly. This was a very simple example. There would be scenarios where in part of the function would be evaluated based on the first param and the other part on the second. So you can create a partial function by providing it with the first param and then reuse the partial function repeatedly for multiple different second params.
I will be assuming that you mean to ask the difference between the invocation of functions which appear like:-
someFunction(x, y)
someFunction(x)(y)
This happens with the use of Closures which happens to be a concept wherein an inner function can carry the environment in which it was created.
var sum = function (x){
return function(y) {
return x+y;
};
};
var addWith5 = sum(5);
/*
This will return a function and not a value
addWith5 = function(y){return 5+y;};
*/
console.log(addWith5(5)); // this will return 11
/*
You can also use add function directly
*/
console.log(sum(5)(6)); // this will return 11
/*
The function returned by sum(5), gets called with the parameter (6)
*/
//Try using this, to make it more clear
function a(x){
return x;
}(5);
// returns 5
EDIT
Removed "closures is a JS concept."

Higher order javascript functions

can someone explain to me what is going on in the following code. The function is receiving n as parameter, so where is the m coming from? The whole code is confusing.. if someone can explain?
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
// → true
This is exhibiting a functional programming technique called currying. (related also to partial function appliction)
Greater than > usually takes 2 arguments (one on the left and one on the right). This is a way to feed one at a time.
It might be easier to see what is happening if you call it inline:
greaterThan(10)(11);
As you can see from the example above, the 10 gets passed in for the n parameter and then the 11 gets passed in for the m parameter.
The first application that passes the 10 outputs a function that looks like this:
function(m) { return m > 10; };
This is the first application in the partial application.
From there it is easy to see how the 11 is passed in to get the final result.
So, to break it down:
function greaterThan(n) {
return function(m) { return m > n; };
}
//var greaterThan10 = greaterThan(10); -- is equivalent to:
var greaterThan10 = function(m) { return m > 10; };
console.log(greaterThan10(11)); //--> true
m is 11, passed in during the second call.
When you call greaterThan(10), it returns a new function that looks like:
function(m) {
return m > 10;
}
which is then saved as greaterThan10. This is called currying.
greaterThan is a function that returns another function as a result, m is a paraterer of that returned function. So in your code:
var greaterThan10 = function(m) { return m > 10; };
and
console.log(greaterThan10(11)); is the same as console.log(11 > 10);
when you call function greaterThan it returns another function but not a number of float. Inner function knows about n because it inside function greaterThan.
Because wrapper function returns another function you can call second one like this
var result = greaterThan(10)(11);
first argument 10 will be used for wrapper function but result is function so you can pass arguments for inner function immediately.
this is possible only if you have return function(){...}
you can try something like
var a = function (x){
return function(y){
return function(z){
return x*y*z;
}
}
}
var result = a(5)(3)(8);
You have two functions there.
The n comes from when the first function is called.
The m comes from when the second function (which is the return value of the first function) is called.
greaterThan10 = greaterThan(10);
// ^^ n
greaterThan10(11))
// ^^ returned function
// ^^ m

How to programmatically set the length of a function

The length property of functions tells how long the 'expected' argument list is:
console.log((function () {}).length); /* 0 */
console.log((function (a) {}).length); /* 1 */
console.log((function (a, b) {}).length); /* 2 etc. */
However, it is a readonly method:
f = function (a) {};
alert(f.length); // 1
f.length = 3;
alert(f.length); // 1
Is there a way to programmatically set that length? The closest I've come so far is to use the Function constructor:
f = new Function("a,b,c", "/* function body here */");
f.length; // 3
However, using Function is essentially the same as eval and we all know how bad that is. What other options do I have here?
It turns out the length property on functions is configurable, which means you can use .defineProperty to change the value of length on a function. Example:
function hi() {}
hi.length === 0; // Expected
Object.defineProperty(hi, "length", { value: 5 })
hi.length === 5; // Intriguing
This works in the latest version of Chrome and Firefox, but it does not work in Safari (v9.1.1).
For now, here's the best solution I could think of.
makeFunc = function (length, fn) {
switch (length) {
case 0 : return function () { return fn.apply(this, arguments); };
case 1 : return function (a) { return fn.apply(this, arguments); };
case 2 : return function (a,b) { return fn.apply(this, arguments); };
case 3 : return function (a,b,c) { return fn.apply(this, arguments); };
case 4 : return function (a,b,c,d) { return fn.apply(this, arguments); };
case 5 : return function (a,b,c,d,e) { return fn.apply(this, arguments); };
case 6 : return function (a,b,c,d,e,f) { return fn.apply(this, arguments); };
case 7 : return function (a,b,c,d,e,f,g) { return fn.apply(this, arguments); };
case 8 : return function (a,b,c,d,e,f,g,h) { return fn.apply(this, arguments); };
case 9 : return function (a,b,c,d,e,f,g,h,i) { return fn.apply(this, arguments); };
default : return function (a,b,c,d,e,f,g,h,i,j) { return fn.apply(this, arguments); };
}
};
Example usage:
var realFn = function () {
return "blah";
};
lengthSix = makeFunc(6, realFn);
lengthSix.length; // 6
lengthSix(); // "blah"
Personally, I always cringe whenever I use copy and paste when programming, so I'd be very happy to hear of any better options.
Update
I thought of a method which could work for any arbitrary size, unlike the example above which is limited by how many times you want to copy-and-paste. Essentially, it dynamically creates a function (using new Function) which will return a function of the right size which then just proxies through to whatever function you pass to it. Yeah that does hurt your head. Anyway, I thought I'd benchmark it against the above...
http://jsperf.com/functions-with-custom-length (you can see the 'evil' code there too).
The evil method is many hundreds of times slower than the hacky copypasta method, so there you go.
I am doing something like what you're asking for using roughly the following:
/* Make a new function with a given size */
function SizedFunc(num_args) {
if(SizedFunc.sizedFuncs === undefined) SizedFunc.sizedFuncs = {};
if(SizedFunc.sizedFuncs[num_args] === undefined) {
var argNames = [];
for(var i = 0; i < num_args; ++i) {
argNames.push('arg' + i);
}
SizedFunc.sizedFuncs[num_args] = new Function(argNames, 'return this.apply(null, arguments);');
}
return SizedFunc.sizedFuncs[num_args];
}
This does use a Function constructor but in a strictly limited way and only ever once per function size to create a function wrapper (which is cached for that size) after that I use wrapper.bind(real_function) to provide the implementation as a function expression/object.
Advantages are that any size is supported and we aren't hard coding the function definitions but actual function implementations are never done in an 'eval' like way and the string passed to the Function constructor is always the same.
/* ---- example ---- */
var a = SizedFunc(4).bind(function() { console.log.apply(null, arguments); });
var b = SizedFunc(4).bind(function(a, b, c, d) { console.log(a + b, c + d); });
console.log(typeof a); // -> function
console.log(typeof b); // -> function
console.log(a.length); // -> 4
console.log(b.length); // -> 4
a(1, 2, 3, 4) // -> 1 2 3 4
a(1, 2, 3, 4, 5); // -> 1 2 3 4 5
b(1, 2, 3, 4) // -> 3 7
I'm sure there are plenty of reasons this is bad, too (starting with the use of bind meaning functions created this way can't be bound to an object) but it is useful in situations where one needs to be able to create a function of arbitrary length dynamically.
According to the ECMA Script standard, revision 5.1 on page 103, the .length parameter on a Function object is not writable so it is set when the function is declared and not changable (if implemented per spec).
Thus, the only way to create a function with a particular .length upon demand is to either have a bunch of functions lying around of various length (as nickf suggests), create a Function object (as you've already mentioned) or use eval() with a dynamically created string. I don't know what problem yu're actually trying to solve, but I personally find nothing wrong with using eval() if you know the source of the code you're using it with and have a way of either checking it or knowing what it will or won't have in it. In this case, programmatically generating a certain number of parameters in a string before calling eval() on it poses no security risk I'm aware of.
If this is all your own code, you can just create a new property on the function .dynLength that is mutable and set it to whatever you want and have your code use that.
There’s an npm module util-arity which does what you want:
const arity = require('util-arity');
arity(3, () => {}).length; //» 3

Categories