Created
March 20, 2023 14:39
-
-
Save hokevins/e122961aa745e4ddee8fc0a998bc0eb6 to your computer and use it in GitHub Desktop.
Notes on functional programming fundamentals: Closure vs Partial Application vs Currying
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Functional Programming: Closure, Partial Application, and Currying | |
const add = (...args) => args.reduce((a, e) => a + e, 0); | |
console.log(add(5, 3)) // 8 | |
/* | |
Partial application allows us to fix a function’s arguments. This lets us derive new functions, with specific behavior, from other, more general functions. | |
Partial application: A function returning another function that might return another function, but each returned function can take several parameters. | |
*/ | |
const partial = (fn, ...args) => { | |
return (...moreArgs) => { | |
return fn(...args, ...moreArgs); | |
} | |
} | |
const add5 = partial(add, 2, 3); | |
/* | |
Closure ensures that inner functions have access to all of the values in its parent function’s scope, even after the parent function has returned. | |
Any time a function returns another function, the returned function has access to any variables initialized within the parent function’s scope. This is a good example of using closure to encapsulate state. | |
*/ | |
// Or using .bind | |
// .bind can also be used to partially apply arguments (like a JS built-in partial function) | |
// .bind returns a new function whose length is decreased based on the number of arguments that have been partially applied | |
// const add5 = add.bind(null, 2, 3); | |
console.log(add5(5, 3)) // 13 | |
/* | |
Currying is the process by which a function of N arguments is implemented as N single-argument functions such that first of them takes in the first argument and returns a function which takes in the 2nd argument and so on, until the Nth single-argument function finally returns the value of the multi-argument function being implemented. | |
Currying is the process of transforming a function that we call all at once with multiple variables, into a series of function calls, where we pass each variable one at a time. | |
Currying: A function returning another function that might return another function, but every returned function must take only one parameter at a time. | |
If you pass fewer arguments than the original function took, the curried function will automatically return the same thing you’d get by calling partial. | |
*/ | |
const curried = (fn) => { | |
return (...args) => { | |
// find the number of arguments (or arity) of a function using .length | |
if (args.length >= fn.length) { | |
return fn(...args); | |
} else { | |
const partiallyApplied = fn.bind(null, ...args); | |
return curried(partiallyApplied); | |
} | |
}; | |
}; | |
const sayHello = (greeting, name) => `${greeting}, ${name}`; | |
const curriedSayHello = curried(sayHello); | |
const sayBonjour = curriedSayHello('Bonjour'); | |
const sayHola = curriedSayHello('Hola'); | |
console.log(sayBonjour('Vraska')); // Bonjour, Vraska | |
console.log(sayHola('Jace')); // Hola, Jace | |
// Currying gives us the best of both worlds: Automatic partial application and the ability to use our original functions. | |
console.log(curriedSayHello('Hello')('Foo')); // Hello, Foo | |
console.log(curriedSayHello('Hello', 'Foo')); // Hello, Foo | |
/* | |
Resources: | |
https://github.com/FullstackAcademy/1802-FSA-NY-Library/blob/master/02-senior/REACTO/week-5-functional-programming/2-steph-curry.md | |
https://www.digitalocean.com/community/tutorials/javascript-functional-programming-explained-partial-application-and-currying | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment