Tuples are commonly used in many languages, though some simply utilize arrays to represent them. We're going to learn what a Tuple is, why it is used, and what differences it may have from a List or Array.
One data structure that is very common in many languages, but won't have a specified data structure in each, is a Tuple.
Now I tend to pronounce this as "toople", since three major dictionaries favor the same, but there are a few alternatives. The most common alternative you may use or hear is "tupple", which is the way I first pronounced the word when I learned the concept.
Whichever way you choose to pronounce it, people will be able to figure out what you're talking about, and realistically we read it more than we say it.
But enough about pronunciation, let's discuss what defines a Tuple.
Let's start off with the very basics. We can create an empty by using empty parens
(). Or alternatively you can call the native
tuple function with no argument and receive the same result, which we can verify by checking equality. This next thing is a quirk with Python, but if you're following a long it's important to know. If I define a tuple with a single element like so
(1), it is going to evaluate to just the value itself. This is because the interpreter reads it as just a value with parens around it. In order to get the interpreter to read it as a tuple, all we have to do is
add a comma after the first element
(1,), and then it becomes the tuple we expected. Technically we don't even need the parens
1,, it's the comma that tells the interpreter it's a tuple. The native
tuple function isn't variadic, meaning it doesn't take unlimited arguments. It wants you to pass an array to convert into a tuple. So we'll just pass in
 an array containing 1, and that'll look exactly the same as using the literal syntax
Okay so now let's demonstrate what is arguably the most common type of tuple, a couple, also known as an ordered pair.
It's just a tuple with two elements. This could certainly just be something like
(1, 2) 1, 2, but let's assume for a moment
that I have a very basic HTTP router. If a request is valid I want to return something to show it is a successful request,
and provide the body for the response. If it is unsuccessful, I want to let the consumer know and provide an error why.
So let's represent these hypothetical requests as new functions right here in the REPL. First we will generate a new function called
good_request(). Assuming it is successful I will respond with
(200, "Hello, world!"), where the HTTP status code would be a 200, and the body a simple greeting. This fits in with the idea earlier where I mentioned that a tuple is used to store heterogeneous, but related data.
Next we'll make a function called
bad_request that returns a 500 and
(500, 'Server is broken') some error,
in this case simply telling us the server is broken.
As you may expect, if I call these functions I get their returned tuple as the result.
Now what can I do with this. Well if I call
x = good_request(), I can then access the status code and the body by their appropriate indices. That seems a bit silly to me to use data like this, so lets utilize some destructuring. What I mean by destructuring is that I am going to pull apart the elements of my tuple and assign them to variables. In Python, I think it is more common to call it
unpacking a tuple, and it syntactically looks as though
good_request() returns multiple values.
Instead of saying that we assign the variable x to the return type of good_request, we are instead going to assign
body to the result of
good_request(). Now within this scope I can use
status to represent our status code, or element 0 of the tuple, and
body to represent element 1. The same works for arrays in Python, I can easily just write
foo, bar = [1,2] and now
foo is 1 and
bar is 2.
So with this kind of syntax available, it makes using tuples a bit more appealing than passing multiple arguments and pretending they're related. It's sometimes a better fit than creating a new object, class, or map as well. For our next example I am going to hop into a browser and we're going to do something tuples excel at - representing coordinates.
My page here is very basic - I have a canvas element that I fetch by
id, then I grab it's context for some 2D drawing. These four lines I'm simply setting up the drawing context a bit and can largely be ignored. Let's look at our list of coordinates here. They're provided as object literals right now, but another common way I've seen in the wild is that a full
Point, which may as well simply just be the object literal since the class doesn't do much on its own.
I think that this kind of system benefits from tuples, because we are providing a point over two axis. The x and y coordinates are related and necessary to create the point, so grouping them together makes sense. Our objects work fine for this, but simply using tuples can suffice. Let's see how that would look. We'll just replace
new Point with an open bracket, and replace the closing paren with a closing bracket. Now are coordinates are represented as an array of tuples, or technically an array of arrays since JS doesn't have real tuples. Now down here in the
plotLine function, we could technically keep using the variable
pair and now access
So any of these options are ultimately okay, I just feel that having these values named x and y in an object when we know it's a list of x and y coordinate pairs doesn't win us a lot. I find that an array of arrays or tuples matches up well with the mathematical representation of a tuple and coordinate pairs so it's my preferred choice in this instance.
Be sure to look at the data structures native to your language of choice and see what works out better for your situations. In Python, tuples are lightweight, have computed lengths at compile time, and are immutable. Sometimes that's preferable to a list or a map, and other times it's not. It's all about tradeoffs, so doing a little bit of research ahead of time can save you a lot of headaches later.