This content originally appeared on DEV Community and was authored by francesco agati
Partial functions, or partial application, is a concept in functional programming where a function, instead of being called with all its arguments at once, is called with a subset of its arguments, returning a new function that takes the remaining arguments.
What is Partial Application?
Partial application refers to the process of fixing a few arguments of a function and generating a new function that takes the remaining arguments. It is different from currying, although they are related concepts. Currying transforms a function with multiple arguments into a series of unary (single-argument) functions, while partial application fixes a few arguments and returns a function expecting the rest.
Implementing Partial Functions in JavaScript
JavaScript, being a flexible language, allows for easy implementation of partial functions. Let’s look at some examples:
-
Manual Partial Application
const add = (a, b, c) => a + b + c; const partialAdd = (a) => (b, c) => add(a, b, c); const addFive = partialAdd(5); console.log(addFive(3, 2)); // 10In this example,
partialAddis a function that partially applies the first argument of theaddfunction, returning a new function that takes the remaining two arguments. -
Generic Partial Application Function
A more generic approach can be used to create a utility for partial application:
const partial = (fn, ...fixedArgs) => (...remainingArgs) => fn(...fixedArgs, ...remainingArgs); const add = (a, b, c) => a + b + c; const addFive = partial(add, 5); console.log(addFive(3, 2)); // 10 const addFiveAndThree = partial(add, 5, 3); console.log(addFiveAndThree(2)); // 10Here, the
partialfunction takes a functionfnand a set of fixed argumentsfixedArgs. It returns a new function that takes the remaining arguments and applies them to the original function along with the fixed ones. -
Using Utility Libraries
Libraries like Lodash provide built-in support for partial functions, making them easy to use:
const _ = require('lodash'); const add = (a, b, c) => a + b + c; const addFive = _.partial(add, 5); console.log(addFive(3, 2)); // 10 const addFiveAndThree = _.partial(add, 5, 3); console.log(addFiveAndThree(2)); // 10Lodash’s
_.partialsimplifies the creation of partial functions, enhancing code readability and maintainability.
Benefits of Partial Application
- Reusability: Partial application allows you to create specialized functions from more general ones, promoting code reuse.
- Modularity: Breaking down complex functions into simpler, partially applied functions enhances modularity and separation of concerns.
- Readability: Code that uses partial application can be more expressive and easier to understand, as it abstracts away some of the complexity.
Practical Applications of Partial Functions
-
Event Handlers
Partial functions can be useful for creating event handlers with pre-configured parameters:
const greet = (greeting, name) => console.log(`${greeting}, ${name}!`); const greetHello = partial(greet, 'Hello'); document.querySelector('#button1').addEventListener('click', () => greetHello('Alice')); document.querySelector('#button2').addEventListener('click', () => greetHello('Bob'));In this example,
greetHellois a partially applied function that fixes thegreetingargument, making it easier to create event handlers with a consistent greeting. -
API Requests
Partial application can streamline the process of making API requests with common parameters:
const fetchData = (url, method, headers) => { // Simulate an API request console.log(`Fetching ${url} with method ${method} and headers ${JSON.stringify(headers)}`); }; const fetchWithGet = partial(fetchData, 'GET', { 'Content-Type': 'application/json' }); fetchWithGet('https://api.example.com/data'); fetchWithGet('https://api.example.com/users');Here,
fetchWithGetis a partially applied function that fixes themethodandheadersarguments, simplifying the process of making API requests with consistent configurations. -
Logging
Partial functions can be used to create specialized logging functions:
const log = (level, message) => console.log(`[${level}] ${message}`); const info = partial(log, 'INFO'); const error = partial(log, 'ERROR'); info('This is an informational message.'); error('This is an error message.');In this example,
infoanderrorare partially applied functions that fix thelevelargument, making it easier to log messages with consistent severity levels.
This content originally appeared on DEV Community and was authored by francesco agati