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
Related
function multFn(num){
return function(factor){
return factor*num
}
}
var multFive=multFn(5)
console.log(multFive(2)) // outputs 10
The question?:
How does JS know that when I console.log(multFive(2)) that the 2 should be given to the factor parameter? I know that multFn will return a pointer to the method inside it. But I don't get how the 2 gets assigned to factor.
Calling the first function causes the inner one to be returned to your variable. When you invoke that function, the argument you pass goes to the parameter the second function is expecting.
When you run this first line:
var multFive = multFn(5);
The outer function (multFn) is invoked and 5 is received as num, so the function operates like this:
function multFn(5){
return function(factor){
return factor * 5
}
}
But, that function has a return in it that returns the inner function to your multFive variable, so you wind up with this:
var multFive = function(factor){
return factor * 5;
}
Finally, when you invoke multFive and pass it a 2, the 2 becomes the value of the factor argument that the function is expecting.
console.log(multFive(2));
Causes:
function(2){
return 2 * 5;
}
And, 2 * 5 = 10.
NOTE: I've shown what the functions will execute based on the code you've supplied. There is an advanced concept in JavaScript, called "Closures" that could make it so that the outer function doesn't always have to statically run with 5 as its value. But, for the purposes of your question, that's not relevant.
This is really an example of function currying. Essentially you are returning a function from a function, with some of the needed values already specified during the creation of the returned function.
Calling multFn(5) creates a closure around an anonymous function, and that closure has a reference to num as being 5.
The function that is returned is equivalent to:
function(factor){
var num=5;
return num * factor;
}
and is assigned to the reference multFive.
Inside your console.log(multFive(2)) you are calling that returned function multFive with the argument 2, and you get your result of 2*5=10.
I think your confusion because you think that the result of the assignment:
var multFive = multFn(5);
Will be something like this:
var multFive = function multFn(num) { //num is passed 5
return function(factor) {
return factor * num;
};
}
But that's not the case. It will actually be something like this:
var multFive = function(factor) {
return factor * num;
}
And the value 5 is assigned to the num variable in the closure. On the next line:
console.log(multFive(2));
You're passing 2 directly to the factor parameter and it will be multiplied by the value of num that was stored in the closure earlier.
To see that in action (a proof of that), print out the multFive:
console.log(multFive);
Here is a funny quiz, try to guess the output and then run it to see:
function multFn(num) {
setTimeout(function() {
num = 3;
}, 500);
return function(factor) {
return factor * num;
};
}
var multFive = multFn(5);
console.log(multFive(2)); // outputs 10
setTimeout(function() {
console.log(multFive(2)); //what will the output be here?
}, 1000);
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));
I am a beginner at Javascript and am running into a little problem. It is a homework problem, but it is graded based on completion only, so I am only trying to figure out the right answer for myself.
I am supposed to define a function, repeatUntil, that takes in two other functions, say f(returns a number) and g (returns a boolean value). The functionality of repeatUntil is to repeat function f at least once until g returns true.
Here is what I have so far:
function repeatUntil(f, cond) {
var f1;
do{
f1 = f;
return f1;
}
while(cond(f1()));
}
And here is the tester/how we call it:
var print = console.log;
var r = repeatUntil(function(x) { return x + x }, function(x) { return x >= 20 })
print(r(2))
print("Expected: 32")
The function runs, but my problem right now is storing the updated value of x from the repeatUntil function. Right now the function only runs once, and the condition is not updated because I cannot pass in the updated value of x into the function g. I tried putting the result of f() into a variable, but it will only return a function and not a number.
Any help/advice would be greatly appreciated. Thank you!
Combining the existing comments into an answer.
Since you need to call r(), your function needs to return another function.
The do loop will run exactly once because you return in the body of the loop
Code
function repeatUntil(f, cond) {
return function() {
while(cond(f()));
}
}
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."
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