Skip to content

Instantly share code, notes, and snippets.

@hokevins
Created March 20, 2023 14:39
Show Gist options
  • Save hokevins/e122961aa745e4ddee8fc0a998bc0eb6 to your computer and use it in GitHub Desktop.
Save hokevins/e122961aa745e4ddee8fc0a998bc0eb6 to your computer and use it in GitHub Desktop.
Notes on functional programming fundamentals: Closure vs Partial Application vs Currying
// 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