Just started doing some JS stuff and can't get my head around something. I have the following task:
Write a function that adds a number passed to it to an internal sum
and returns itself with its internal sum set to the new value, so it
can be chained in a functional manner. Input: Your function needs to
take one numeric argument. Output: Your function needs to return itself
with an updated context.
I came up with the following code after some hints from here and there:
function add(num) {
let sum = num;
function func(num2) {
sum += num2;
return func;
}
func.toString = function() {return sum;};
return func;
}
console.log(
add(1)
);
console.log(
add(1)(6)(-3)
);
What exactly do func.toString = function() {return sum;} and return func do? Before that I get it - closure and returning a function and etc.
Related
Can someone please explain to me this bit of code
return pipe(...fns)(this);
I understand if we didn't have (this), so we returned the reduced functions but (this) confused me.
Full source code here. line 72
https://stackblitz.com/edit/typescript-hv4ntb
It is the same as this:
const pipeFunction = pipe(...fns); // pipe returns a function
const result = pipeFunction(this); // call the returned function with this as argument
return result; // return the result
So if you ever see something like variable(...)(...) you should assume that the variable evaluates to a function that returns a function, like this perhaps:
const variable = (a) => (b) => a + b;
variable(4)(2);
// ==> 6
const partial = variable(8)
[1, 2, 3].map(partial);
// ==> [9, 10, 11]
Javascript is said to have first-class functions (you can read more here on MDN), meaning that you can do with functions what you can do with other types. Storing them into a variable, passing them as argument to other functions, as well as using them as return value from other functions.
The thinking is, just think of functions as values.
In your use-case, a function is just being returned from another function:
function multiply(times) {
return function(number) {
return number * times;
};
}
// as you can see, we are storing the "returned function"
// resulted from calling `multiply` into the `double` variable.
const double = multiply(2);
console.log(
double(5)
);
Now, of course, you could short-circuit the double variable,
and just call the returned function straight away.
function multiply(times) {
return function(number) {
return number * times;
};
}
console.log(
multiply(2)(5)
);
I am learning javascript, and I am not able to understand the following piece of code.
const increment = (function() {
return function test(number, value) {
return number + value;
};
})();
console.log(increment(5, 2)); // output 7
My attempt at understanding
I removed the () on line 5, and then ran the following code.
const increment = (function() {
return function test(number, value) {
return number + value;
};
});
console.log(increment(5, 2));
This returns the output test(number, value) which I can understand. The increment variable points to the function test.
However, I don't understand how adding () passes the arguments (5,2) to test?
Said another way, if the output of the second code block is test(number, value), the output after adding () is test(number,value)() which seems meaningless.
It calls self-invoking.
If you write function like that (function foo(){})() then foo will be immediately called and result will be returned.
So as result in increment you have test function.
And then you call it with arguments.
increment(5, 2) // test(5, 2)
Here is some info about that
() at the end of the function immediately calls it - it's called IIFE ("Immediately invoked function expression").
When calling it with increment(5, 2) - you are actually calling the test function that is returned by the IIFE.
Your question is regarding the Javascript Immediate Functions.
First, we need to know what a function is, which is basically a block of code that returns a value.
And to declare a function in Javascript, one way is this:
function a() {
return "in this case, a string";
}
If we do:
const variable = function () {
return "in this case, a string";
};
console.log(variable); // Function
But Immediate Functions, as the name implies, are functions that are executed immediately after being defined, so, the value that the function returns is the value that will be given to the variable:
const variable = (function () {
return "in this case, a string";
})();
console.log(variable); // "in this case, a string"
About removing parentheses:
// This is
const increment = (function() {
return function test(number, value) {
return number + value;
};
});
// ...the same as this
const increment = function() {
return function test(number, value) {
return number + value;
};
};
We use parentheses just to isolate this expression (which is the function) and execute it right afterwards:
// Now the parentheses make sense,
// because we need it to execute the function right after it is defined
const increment = (function() {
return function test(number, value) {
return number + value;
};
})();
Read more about Immediate Functions here
I am reading the javascript manual and I have wtote following code:
//sum
function sum(arg1) {
var sum = arg1;
function f(arg2) {
sum += arg2;
return f;
};
f.valueOf = function () {
return sum;
};
f.toString = function () {
return sum;
};
return f;
}
and I execute it like this:
console.log(sum(1)(2)(3)(4));
According the manual console.log should output the result of valueOf function
but it output
function 10
please explain this behaviour.
According the manual console.log should output the result of valueOf function
I don't know what "manual" you're talking about, but in general, console.log doesn't call valueOf on what you output. The implementations of console.log vary from JavaScript engine to JavaScript engine, but in general they try to give you more useful information than calling valueOf would.
If you want to trigger valueOf, you'll need to do that intentionally, for instance:
console.log(sum(1)(2)(3)(4).valueOf());
// ------------------------^^^^^^^^^^
or (since your function is designed to produce a number):
console.log(+sum(1)(2)(3)(4));
// ---------^
Example:
function sum(arg1) {
var sum = arg1;
function f(arg2) {
sum += arg2;
return f;
};
f.valueOf = function () {
return sum;
};
f.toString = function () {
return sum;
};
return f;
}
console.log(sum(1)(2)(3)(4).valueOf());
// ------------------------^^^^^^^^^^
console.log(+sum(1)(2)(3)(4));
// ---------^
Look in the actual browser console; the Stack Snippets console doesn't quite do what the real browser console does.
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