clubmate.fi

A good[ish] website

Web development blog, loads of UI and JavaScript topics

Currying in JavaScript

Filed under: JavaScript— Tagged with: functional

Currying explained simply with few examples.

The name "currying", coined by Christopher Strachey in 1967[citation needed], is a reference to logician Haskell Curry.

This guy has a language and a programming technique named after him!

The basic idea of currying

In simple terms, a curried function is a function that returns a function. Currying is generally good when you want to prepopulate a function, like shown in the examples below.

In JavaScript, curried function looks something like this:

function add(x) {
  return function (y) {
    return x + y
  }
}

add(1)(1) // 2

But currying syntax somehow clicks together with arrow functions:

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

add(1)(1) // 2

JavaScript is cool, it can access the first function’s params in the inner function like nothing.

Calling a curried function

If you want to call a curried function you do it like this:

const one = add(1)
const two = one(1)
console.log(two) // 2

You’re adding into it as you go.

Or:

add(1)(1)

A curried API call example

Here’s a more realistic scenario, something that might happen in everyday work life. A curried function where the outer function can be prepopulated with a URL, and the inner function takes the required options:

// The curried function that maybe lives in a shared directoryconst getData = url => async options => {
  const params = new URLSearchParams(options)
  const response = await fetch(`${url}?${params.toString()}`)

  return response.json()
}

// Prepopulate it with different API endpointsconst getEmployees = getData('https://hub.dummyapis.com/employee')
const getProducts = getData('https://hub.dummyapis.com/products')

;(async () => {
  // Call the second half of the curried functions with needed options  const employees = await getEmployees({ noofRecords: 2 })
  const products = await getProducts({ noofRecords: 3, currency: 'usd' })

  console.log({ employees, products })
})()

Play around with a working demo:

Edit cyrrying-test CodeSandbox

Currying a callback function

For example in React you get to deal with events and callback functions a lot.

In the following example that clickHandler fn takes an event and an id:

const Foo = ({ id }) => {
  const handleClick = (event, id) => {    if (event.target.id === id) {
      // something...
    }
  }

  return (
    <button id="foo" onClick={event => handleClick(event, id)}>      Click
    </button>
  )
}

You can write it more concisely by currying the handleClick callback, the click event will be passed to the innermost function:

const Foo = ({ id }) => {
  const handleClick = id => event => {    if (event.target.id === id) {
      // something...
    }
  }

  return (
    <button id="foo" onClick={handleClick(id)}>
      Click
    </button>
  )
}

That’s purely cosmetic though, I can understand if someone finds that to be a bit extra.

Other examples

A random example of currying: styled-components syntax assumes currying when extending components while using the style object syntax:

const RedParagraph = styled(Paragraph)({
  color: 'red'
})

Conclusions

You can probably sail your JavaScript career through without ever writing a curried function, but in some cases it feels very elegant.

Hope this was helpful, thanks for perusing my little blog article!

Comments would go here, but the commenting system isn’t ready yet, sorry. Tweet me @intterne if you want to make a correction etc.

  • © 2022 Antti Hiljá
  • About
  • Follow my new Twitter account → @intterne
  • All rights reserved yadda yadda.
  • I can put just about anything here, no one reads the footer anyways.
  • I love u!