April 01, 2021
0 strokes bestowed

What is a Tuple?

edit

As a JavaScript developer, we don't have an official Tuple data type like we do Array or Object, but that doesn't mean we don't have tuples in our code. In a post I'm working on, I realized I have several tuples in my code and it might be worth taking a minute to explain what a tuple is.

We get tuples from mathematics. A tuple is a finite, ordered list of elements. In JavaScript, this would be likely represented as an array. I can create a tuple to represent a person like so:

const personTuple = ['Kyle', 35, 'Portland, OR']

Looking at personTuple, we can see that it is a finite length of 3 items, and that those items are in a particular order: name, age, and location.

When might I use a tuple?

A tuple can be a convenient way to create and use key/value data.

"But Kyle, where are the keys? I don't see any!"

Good question.

If objects are explicit key/value stores, we can think of tuples as implied key/value stores. Remember, a tuple is an ordered list. We can't jumble up the items of the list without breaking the contract of the tuple. Therefore, we can infer the keys of a tuple by the order of the list.

For example, if I have a function that receives a personTuple, I should be able to safely array destructure and get the right order of values every time.

function personIntro(personTuple) {
  const [name, age, location] = personTuple

  return `Hi, my name is ${name}. I am ${age} years old from ${location}.`
}

Array destructuring makes the implicit key/value store of the tuple pretty clear.

Wait, are we using tuples all the time?

You are if you're using React! Think about what is returned to you everytime you use useState or useReducer. It's a tuple!

const [state, setState] = React.useState()

What is [state, setState] but a tuple? It is a [value, setter] tuple. Same goes for useReducer, but swap setter for dispatcher.

If I create a custom hook that returns [state, handlers], what have I done but created a tuple?

function useSwitch(initialState = false) {
  const [state, setState] = React.useState(initialState)

  const handlers = React.useMemo(
    () => ({
      on: () => {
        setState(true)
      },
      off: () => {
        setState(false)
      },
      toggle: () => {
        setState(s => !s)
      },
    }),
    []
  )

  return [state, handlers]
}

Turns out tuples are everywhere.

What makes a tuple different than an array?

An array is generally a list of items of unknown and unforeseen length. It can hold a few items, a lot of items, or no items at all.

It's also more common for an array to be homogenous. That is, all the items in the list are the same type. You have an array of strings, an array of numbers, an array of person objects.

Tuples, on the other hand, are lists of items of known, foreseen length. They have a finite number of items. They are more often hetergenous, as well. Our personTuple from before had two strings and a number.

Tuples and type systems in JS

The distinctions between arrays and tuples are rather clear when using a type system with JavaScript, such as TypeScript or Flow. If we have an array of numbers, we may type it in either of the following ways in TypeScript.

const nums: Array<number> = [1, 2, 3, 4, 5, 6]

const nums2: number[] = [1, 2, 3, 4, 5, 6]

In either case, it's pretty clear that what we're returning is a homogenous array of numbers. It doesn't matter what length the array is, just that each item in it is of the same type.

Compare this to typing a custom React hook that returns state and handlers as a tuple.

type SwitchTuple = [
  state: boolean,
  handlers: {
    on: () => void;
    off: () => void;
    toggle: () => void;
  }
]

function useSwitch(initialState = false): SwitchTuple {
  const [state, setState] = React.useState(initialState)

  const handlers = React.useMemo(
    () => ({
      on: () => { setState(true) },
      off: () => { setState(false) },
      toggle: () => { setState(s => !s) }
    }),
    []
  )

  return [state, handlers]
}

Instead of a homogenous array type, like number[], we've instead given it a tuple type, clearly demarcating the state and handlers to be returned.

Summary

Tuples are ordered lists of finite length that can be used as implicit key/value stores. While JavaScript doesn't have a Tuple yet (there is a TC39 proposal to add it), you might already be using them. You may find them useful for particular algorithms, writing custom hooks and more.

Sharing this article on Twitter is a great way to help me out and I really appreciate the support.
+0
Liked the post? Click the beard a few times.
Tags
Older Post: Conditional React Hooks

Let's talk some more about JavaScript, React, and software engineering.

I write a newsletter to share my thoughts and the projects I'm working on. I would love for you to join the conversation. You can unsubscribe at any time.

Introduction to State Machines and XState Logo
Introduction to State Machines and XState

Check out my courses!

Liked the post? You might like my video courses, too. Click the button to view this course or go to Courses for more information.
View on egghead.io
Kyle Shevlin's face, which is mostly a beard with eyes
Kyle Shevlin is a software engineer who specializes in JavaScript, React and front end web development.