Currying and Partial Application. An introduction to higher order…
By: Rodrigo Botti
Tags: JavaScript, Curry, Partial Application, Functional Programming, Higher Order Function

Higher Order Functions

Before jumping right into explaining currying and partial application, first we need to understand what higher order functions are.

"A higher order function is a function that takes a function as an argument, or returns a function." — Eric Elliot

Let's take a look at some examples of higher order functions from Javascript's built-in Array type. Array instances have the methods map, filter and reduce. Each is a higher order function that receives another function as an argument.

const numberArray = [1, 2, 3] const double = val => val * 2 const doubled = numberArray.map(double)

// > [2, 4, 6] const isOdd = val => val % 2 !== 0 const odds = numberArray.filter(isOdd)

// > [1, 3] const add = (x, y) => x + y const sum = numberArray.reduce(add, 0)

// > 6

As you can see, the functions take a function as a parameter. But why? Why not just loop over arrays? As it turns out, transforming each element (mapping), filtering/removing elements (filter) and accumulating the elements (reduce) of an array are common operations. These are higher order functions, abstract iterations where something happens to each element (transformation, predicate evaluation, and accumulation respectively).

What do we mean by that? Imagine now you want to only get even numbers from the array. All you have to do is write a predicate function that identifies even numbers and use .filter. In an imperative "for-loop" implementation we would have to rewrite the whole loop just to change the "if" condition in it.

Curry

"A curried function is a function that takes multiple arguments one at a time." — Eric Elliot

Let's say we have a two parameter function that adds two numbers:

const add = (x, y) => x + y

We would say add is curried when it is in the form

const add = x => y => x + y

Note that it is a function that (takes a single parameter) returns another function that (takes a single and the last parameter) finally returns the result i.e. add is a higher order function since it returns a function.

Why do that? To achieve something called partial application.

Consider the curried add function above. We could do something like this:

const increment = add(1)

The increment function is the add function but with x = 1! Which means that when we call:

increment(2) // 3

increment(5) // 6

Partial Application

Now imagine that extended to function of N arguments where any number of them can be partially applied. This is partial application.

"A partial application is a function which has been applied to some, but not yet all of its arguments. In other words, it’s a function which has some arguments fixed inside its closure scope. A function with some of its parameters fixed is said to be partially applied." — Eric Elliot

Notice the difference? Curried functions take one argument at a time whereas partially applied functions can take many arguments at a time.

Some functional programming libraries give you the power to turn a function of many arguments, making it possible to have it partially applied.

Something that can cause confusion: these libraries usually give this function the name curry (instead of partial, for example). One such example is ramda and its curry function:

const { curry } = require('ramda') const add = curry((x, y) => x + y) add(1)(2) === add(1, 2) // true

Note: we can call it with one argument at a time or both at the same time whereas in the previous curried case we have to call it one at a time exclusively.

Now let's think about having a function with three arguments:

const a = curry((x, y, z) =>

x + y + z

) // because `curry` allows for partial application:

a(1)(2)(3) === a(1, 2)(3) === a(1)(2, 3) === a(1, 2, 3) // true

Side note — you could implement your own version of curry like this:

const curry = (fn, n) => {

const arity = n || fn.length

return (...params) =>

params.length >= arity

? fn(...params)

: curry(

(...rest) => fn(...params, ...rest),

arity - params.length

)

}

Now going back to the subject of partial application. Why would we do something like that?