Developers that used to write in functional languages feel good with JavaScript because the language supports functional concepts. One of them is partial application.
Partial application is when we duplicate a function but with some of its arguments already applied. It sounds a bit weird, but it is a helpful technique. Consider the following:
function createLogMessage(type, message) {
return `${type}: ${message}`;
}
and some of its potential usage:
console.log(createLogMessage('Error', 'Ops!'));
// Error: Ops!
console.log(createLogMessage('Info', 'Data delivered.'));
// Info: Data delivered.
Think about how we have to use createLogMessage
everywhere in our application. We have to specify the type all the time. We can extract that to a constant, but it is still a duplication.
We can make our life easier by using partial application.
function createLogMessage(type, message) {
return `${type}: ${message}`;
}
function partial(func, ...args1) {
return (...args2) => {
return func(...args1, ...args2);
}
}
const onError = partial(createLogMessage, 'Error');
const onInfo = partial(createLogMessage, 'Info');
console.log(onError('Ops!'));
// Error: Ops!
console.log(onInfo('Data delivered.'));
// Success: Data delivered.
We not only avoid repeating ourselves, but we have these little helpers onError
and onSuccess
.
JavaScript has a built-in method that is making a partial application. We mentioned it when we were talking about scope. That is the bind
function. This last snippet we could replace with the following:
const onError = createLogMessage.bind(null, 'Error');
const onInfo = createLogMessage.bind(null, 'Info');