ES6 arrow functions returning different values - javascript

I'm new to ES6 and I'm trying to figure out what the difference is between this:
const func1 = (x, y) => x * y * 3
and this:
const func2 = x => y => x * y * 3
I have tried running it and I see that the func1(1,1) returns 3 and func2(1) returns 1.
What are the differences and benefits of one or the other?
In what circumstances would you use func2?
Can someone demonstrate how you would use func2?

const func1 = (x, y) => x * y * 3 is a standard arrow function that translates to this:
const func1 = function (x,y) {
return x * y * 3;
}
Whereas,
const func2 = x => y => x * y * 3 is a curried function where you have a function within another function like this:
const func2 = function (x) {
return function (y) {
return x * y * 3;
}
And yeah, as CRice mentioned below, you have to call the parameters spearately with func2 like this:
console.log(func2(a)(b));
As opposed to the standard:
console.log(func1(a,b));
Currying is useful in both practical and theoretical settings. In
functional programming languages, and many others, it provides a way
of automatically managing how arguments are passed to functions and
exceptions. In theoretical computer science, it provides a way to
study functions with multiple arguments in simpler theoretical models
which provide only one argument.
So func2 is a function that can be used in situations where for example, you have to return an 'abc' message if certain requirements are met or run a new function with a different logic if the initial requirements are not met.
Quoted Section via - Wikipedia | Currying

Function two is a curried version of function one. That means that instead of taking a pair of arguments, you pass the first argument in, and it will return you a new function to which you can pass the second argument separately.
Curried functions are useful for creating partially applied functions, among other things. So for your example, you might use those function like so:
const func1 = (x, y) => x * y * 3
const func2 = x => y => x * y * 3
// Two different calling syntaxes, same result:
console.log(func1(2, 3)) // 18
console.log(func2(2)(3)) // 18, note the call chain: (2)(3).
// This is because func2 returns another function.
// You can use that function to partially apply your operation:
const times6 = func2(2);
// Then you can use that elsewhere:
console.log(times6(3)); // 18
console.log(times6(10)); // 60

Related

Closure with a Lazy Adder Function

I'm stuck on a problem that uses a closure function to add the arguments of subsequent functions into a sum function:
Write a function named: lazyAdder(firstNum). The lazyAdder function
will accept a number and return a function. When the function returned
by lazyAdder is invoked it will again accept a number, (secondNum),
and then return a function. When the last mentioned function is
invoked with a number, (thirdNum), it will FINALLY return a number.
See below for examples!
Example 1:
let firstAdd = lazyAdder(1);
let secondAdd = firstAdd(2);
let sum = secondAdd(3);
console.log(sum); // prints 6
Example 2:
let func1 = lazyAdder(10);
let func2 = func1(20);
let total = func2(3);
console.log(total); // prints 33
I tried:
const lazyAdder = f => g => h => x => f(g(h))(h(x));
Thinking it takes in two function inputs (firstNum + secondNum = sum1), then adds a third (thirdNum + sum1 = sum2).
This did invoke the function twice; however, it did not return the sum - it returned an anonymous function.
If I get it correctly, what you are tasked to do is to perform a sum in a sequence of evaluations (i.e. pass arguments at different times). In a non-lazy approach, you would simply make a function sum which takes 3 parameters x, y and z and sum this: sum(1, 2, 3) = 7. Now to do this the "lazy" way, you have to perform an operation on this function called currying. I suggest reading up on this, as this is essentially what is asked.
Currying such a function can be done quite easily in JavaScript. As you showed, you can just chain the arguments in a function declaration:
const func = arg1 => arg2 => arg3 => ... // Some logic performed here
Now you can call this function 3 times until it returns something other than a closure; a value.
How do you make sure that when you func(1)(2)(3) it returns the sum, which is 6?
Since I suspect this is a homework assignment, I do not want to give you the plain answer. Therefore, it is up to you to define what logic should be put inside the function to sum these values. What is important is that the definition I gave, is already a definition of lazy evaluation.

Javascript Sequence of Function Example

function makeMultiplier(multiplier) {
var myFunc = function (x) {
return multiplier * x;
};
return myFunc;
}
var multiplyBy3 = makeMultiplier(3);
console.log(multiplyBy3(10));
So I got this example from an online course, the console prints: 30
I don't exactly understand how the value 30 was obtained, below is what I think is how it is executed, but please do correct me if false.
I assume first that the value of multiplier becomes 3, then the function makeMultiplier returns 3 * X.
From here, by assigning var multiplyBy3 = makeMultiplier(3), essentially multiplyBy3 is now a function that returns 3 * X.
Therefore when 10 is plugged in, it returns 3 * 10 = 30.
Yes, you are correct, remember that functions can be passed around to and from variables and other functions.
makeMultiplier returns a reference to a function closure, it doesn't execute it yet.
var multiplyBy3 = makeMultiplier(3); Puts the value 3 into the closure function, and returns a reference to it (still doesn't execute it yet).
At this stage we have:
function multiplyBy3(x) {
return 3 * x;
}
console.log(multiplyBy3(10));
multiplyBy3(10) calls the reference to the closure function and passes in 10.
The example you posted is also referred to as "currying". Here's another javascript example of currying.
I do recommend that you get in the habit of using ES6 syntax. Your example rewritten in ES6:
const makeMultiplier = multiplier => x => multiplier * x;
const multiplyBy3 = makeMultiplier(3);
console.log( multiplyBy3(10) ); // 30
or
console.log( makeMultiplier(3)(10) ); //30
Correct. This is what is known as a 'closure' (a function that returns another function that has access to the scope of the parent function.

ES6 double arrow parameters (i.e. const update = x => y => { } ) [duplicate]

This question already has answers here:
javascript es6 double arrow functions
(2 answers)
Closed 5 years ago.
What does double arrow parameters mean in the following code?
const update = x => y => {
// Do something with x and y
}
How is it different compared to the following?
const update = (x, y) => {
// Do something with x and y
}
Thanks!
Let's rewrite them "old style", the first one is:
const update = function (x) {
return function(y) {
// Do something with x and y
};
};
While the second one is:
const update = function (x, y) {
// Do something with x and y
};
So as you can see they are quite different, the first returns an "intermediate" function, while the second is a single function with two parameters.
There's nothing special about "double arrow parameters", this is just one arrow function returning another, and can be extended for as many arguments as you'd like. It's a technique called "currying".
From Wikipedia:
In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument.
The benefit of this is that it makes it easier to partially apply and compose functions, which is useful for some styles of functional programming.
Example
Let's say you have a function add which takes two numbers and adds them together, which you might traditionally write like this:
const add = (a, b) => a + b;
Now let's say you have an array of numbers and want to add 2 to all of them. Using map and the function above, you can do it like this:
[1, 2, 3].map(x => add(2, x));
However, if the function had been in curried form, you wouldn't need to wrap the call to add in another arrow function just to adapt the function to what map expects. Instead you could just do this:
const add = a => b => a + b;
[1, 2, 3].map(add(2));
This is of course a trivial and rather contrived example, but it shows the essence of it. Making it easier to partially apply functions also makes it more practical to write small and flexible functions that can be composed together, which then enables a much more "functional" style of programming.
That are called arrow functions, it the new format for functions presented by ES6, in the first example
const update = x => y => {
// Do something with x and y
}
can be traduced to
var update = function (x){
return function (y){
// Do something with x and y..
}
}
in ES5, and is a function that returns a function
is totally different than
const update = function (x, y) {
// Do something with x and y
};
The syntax PARAM => EXPR represents a function that takes a parameter PARAM and whose body is { return EXPR; }. It is itself an expression, so it can be used as the EXPR of other functions:
x => y => { ... }
parses as
x => (y => { ... })
which is the same as
x => { return y => { ... }; }

Are 'currying' and 'composition' the same concept in Javascript?

Recently I read about function composition in a Javascript book, and then on a website I saw someone reference it as currying.
Are they the same concept?
#Omarjmh's answer is good but the compose example is overwhelmingly complex for a learner, in my opinion
Are they the same concept?
No.
First, currying is translating a function that takes multiple arguments into a sequence of functions, each accepting one argument.
// not curried
const add = (x,y) => x + y;
add(2,3); // => 5
// curried
const add = x => y => x + y;
add(2)(3); // => 5
Notice the distinct way in which a curried function is applied, one argument at a time.
Second, function composition is the combination of two functions into one, that when applied, returns the result of the chained functions.
const compose = f => g => x => f(g(x));
compose (x => x * 4) (x => x + 3) (2);
// (2 + 3) * 4
// => 20
The two concepts are closely related as they play well with one another. Generic function composition works with unary functions (functions that take one argument) and curried functions also only accept one argument (per application).
// curried add function
const add = x => y => y + x;
// curried multiplication function
const mult = x => y => y * x;
// create a composition
// notice we only apply 2 of comp's 3 parameters
// notice we only apply 1 of mult's 2 parameters
// notice we only apply 1 of add's 2 parameters
let add10ThenMultiplyBy3 = compose (mult(3)) (add(10));
// apply the composition to 4
add10ThenMultiplyBy3(4); //=> 42
// apply the composition to 5
add10ThenMultiplyBy3(5); //=> 45
Composition and currying are used to create functions. Composition and currying differ in the way they create new functions (by applying args vs chaining).
Compose:
Compose should return a function that is the composition of a list of functions of arbitrary length. Each function is called on the return value of the function that follows. You can think of compose as moving right to left through its arguments.
Example:
var compose = function(funcs) {
funcs = Array.prototype.slice.call(arguments, 0);
return function(arg) {
return funcs.reduceRight(function (a, b) {
a = a === null ? a = b(arg) : a = b(a);
return a;
}, null);
};
};
var sayHi = function(name){ return 'hi: ' + name;};
var makeLouder = function(statement) { return statement.toUpperCase() + '!';};
var hello = compose(sayHi, makeLouder);
l(hello('Johhny')); //=> 'hi: JOHNNY!'
Currying:
Currying is a way of constructing functions that allows partial application of a function’s arguments.
Example:
var addOne = add(1);
var addTwo = add(2);
var addOneToFive = addOne(5);
var addTwoToFive = addTwo(5);
l(addOneToFive); //6
l(addTwoToFive); //7
JSBin with the above examples:
https://jsbin.com/jibuje/edit?js,console

How do I write an arrow function in ES6 recursively?

Arrow functions in ES6 do not have an arguments property and therefore arguments.callee will not work and would anyway not work in strict mode even if just an anonymous function was being used.
Arrow functions cannot be named, so the named functional expression trick can not be used.
So... How does one write a recursive arrow function? That is an arrow function that recursively calls itself based on certain conditions and so on of-course?
Writing a recursive function without naming it is a problem that is as old as computer science itself (even older, actually, since λ-calculus predates computer science), since in λ-calculus all functions are anonymous, and yet you still need recursion.
The solution is to use a fixpoint combinator, usually the Y combinator. This looks something like this:
(y =>
y(
givenFact =>
n =>
n < 2 ? 1 : n * givenFact(n-1)
)(5)
)(le =>
(f =>
f(f)
)(f =>
le(x => (f(f))(x))
)
);
This will compute the factorial of 5 recursively.
Note: the code is heavily based on this: The Y Combinator explained with JavaScript. All credit should go to the original author. I mostly just "harmonized" (is that what you call refactoring old code with new features from ES/Harmony?) it.
It looks like you can assign arrow functions to a variable and use it to call the function recursively.
var complex = (a, b) => {
if (a > b) {
return a;
} else {
complex(a, b);
}
};
Claus Reinke has given an answer to your question in a discussion on the esdiscuss.org website.
In ES6 you have to define what he calls a recursion combinator.
let rec = (f)=> (..args)=> f( (..args)=>rec(f)(..args), ..args )
If you want to call a recursive arrow function, you have to call the recursion combinator with the arrow function as parameter, the first parameter of the arrow function is a recursive function and the rest are the parameters. The name of the recursive function has no importance as it would not be used outside the recursive combinator. You can then call the anonymous arrow function. Here we compute the factorial of 6.
rec( (f,n) => (n>1 ? n*f(n-1) : n) )(6)
If you want to test it in Firefox you need to use the ES5 translation of the recursion combinator:
function rec(f){
return function(){
return f.apply(this,[
function(){
return rec(f).apply(this,arguments);
}
].concat(Array.prototype.slice.call(arguments))
);
}
}
TL;DR:
const rec = f => f((...xs) => rec(f)(...xs));
There are many answers here with variations on a proper Y -- but that's a bit redundant... The thing is that the usual way Y is explained is "what if there is no recursion", so Y itself cannot refer to itself. But since the goal here is a practical combinator, there's no reason to do that. There's this answer that defines rec using itself, but it's complicated and kind of ugly since it adds an argument instead of currying.
The simple recursively-defined Y is
const rec = f => f(rec(f));
but since JS isn't lazy, the above adds the necessary wrapping.
Use a variable to which you assign the function, e.g.
const fac = (n) => n>0 ? n*fac(n-1) : 1;
If you really need it anonymous, use the Y combinator, like this:
const Y = (f) => ((x)=>f((v)=>x(x)(v)))((x)=>f((v)=>x(x)(v)))
… Y((fac)=>(n)=> n>0 ? n*fac(n-1) : 1) …
(ugly, isn't it?)
A general purpose combinator for recursive function definitions of any number of arguments (without using the variable inside itself) would be:
const rec = (le => ((f => f(f))(f => (le((...x) => f(f)(...x))))));
This could be used for example to define factorial:
const factorial = rec( fact => (n => n < 2 ? 1 : n * fact(n - 1)) );
//factorial(5): 120
or string reverse:
const reverse = rec(
rev => (
(w, start) => typeof(start) === "string"
? (!w ? start : rev(w.substring(1), w[0] + start))
: rev(w, '')
)
);
//reverse("olleh"): "hello"
or in-order tree traversal:
const inorder = rec(go => ((node, visit) => !!(node && [go(node.left, visit), visit(node), go(node.right, visit)])));
//inorder({left:{value:3},value:4,right:{value:5}}, function(n) {console.log(n.value)})
// calls console.log(3)
// calls console.log(4)
// calls console.log(5)
// returns true
I found the provided solutions really complicated, and honestly couldn't understand any of them, so i thought out a simpler solution myself (I'm sure it's already known, but here goes my thinking process):
So you're making a factorial function
x => x < 2 ? x : x * (???)
the (???) is where the function is supposed to call itself, but since you can't name it, the obvious solution is to pass it as an argument to itself
f => x => x < 2 ? x : x * f(x-1)
This won't work though. because when we call f(x-1) we're calling this function itself, and we just defined it's arguments as 1) f: the function itself, again and 2) x the value. Well we do have the function itself, f remember? so just pass it first:
f => x => x < 2 ? x : x * f(f)(x-1)
^ the new bit
And that's it. We just made a function that takes itself as the first argument, producing the Factorial function! Just literally pass it to itself:
(f => x => x < 2 ? x : x * f(f)(x-1))(f => x => x < 2 ? x : x * f(f)(x-1))(5)
>120
Instead of writing it twice, you can make another function that passes it's argument to itself:
y => y(y)
and pass your factorial making function to it:
(y => y(y))(f => x => x < 2 ? x : x * f(f)(x-1))(5)
>120
Boom. Here's a little formula:
(y => y(y))(f => x => endCondition(x) ? default(x) : operation(x)(f(f)(nextStep(x))))
For a basic function that adds numbers from 0 to x, endCondition is when you need to stop recurring, so x => x == 0. default is the last value you give once endCondition is met, so x => x. operation is simply the operation you're doing on every recursion, like multiplying in Factorial or adding in Fibonacci: x1 => x2 => x1 + x2. and lastly nextStep is the next value to pass to the function, which is usually the current value minus one: x => x - 1. Apply:
(y => y(y))(f => x => x == 0 ? x : x + f(f)(x - 1))(5)
>15
var rec = () => {rec()};
rec();
Would that be an option?
Since arguments.callee is a bad option due to deprecation/doesnt work in strict mode, and doing something like var func = () => {} is also bad, this a hack like described in this answer is probably your only option:
javascript: recursive anonymous function?
This is a version of this answer, https://stackoverflow.com/a/3903334/689223, with arrow functions.
You can use the U or the Y combinator. Y combinator being the simplest to use.
U combinator, with this you have to keep passing the function:
const U = f => f(f)
U(selfFn => arg => selfFn(selfFn)('to infinity and beyond'))
Y combinator, with this you don't have to keep passing the function:
const Y = gen => U(f => gen((...args) => f(f)(...args)))
Y(selfFn => arg => selfFn('to infinity and beyond'))
You can assign your function to a variable inside an iife
var countdown = f=>(f=a=>{
console.log(a)
if(a>0) f(--a)
})()
countdown(3)
//3
//2
//1
//0
i think the simplest solution is looking at the only thing that you don't have, which is a reference to the function itself. because if you have that then recusion is trivial.
amazingly that is possible through a higher order function.
let generateTheNeededValue = (f, ...args) => f(f, ...args);
this function as the name sugests, it will generate the reference that we'll need. now we only need to apply this to our function
(generateTheNeededValue)(ourFunction, ourFunctionArgs)
but the problem with using this thing is that our function definition needs to expect a very special first argument
let ourFunction = (me, ...ourArgs) => {...}
i like to call this special value as 'me'. and now everytime we need recursion we do like this
me(me, ...argsOnRecursion);
with all of that. we can now create a simple factorial function.
((f, ...args) => f(f, ...args))((me, x) => {
if(x < 2) {
return 1;
} else {
return x * me(me, x - 1);
}
}, 4)
-> 24
i also like to look at the one liner of this
((f, ...args) => f(f, ...args))((me, x) => (x < 2) ? 1 : (x * me(me, x - 1)), 4)
Here is the example of recursive function js es6.
let filterGroups = [
{name: 'Filter Group 1'}
];
const generateGroupName = (nextNumber) => {
let gN = `Filter Group ${nextNumber}`;
let exists = filterGroups.find((g) => g.name === gN);
return exists === undefined ? gN : generateGroupName(++nextNumber); // Important
};
let fg = generateGroupName(filterGroups.length);
filterGroups.push({name: fg});

Categories

Resources