Lists vs. Tuples - What to use and when?

Elixir

Elixir Problem Overview


I am trying to grasp the difference between Lists and Tuples in Elixir. From the Basic Types section of Elixir Guides, I understand that:

  • Lists are stored as Linked Items
  • Updating a List is fast (only when prepending)
  • Fetching List items is slow
  • Fetching List information (size/length) is slow
  • Tuple Elements are stored together
  • Getting Tuple information is fast
  • Fetching Tuple elements is fast
  • Modifying Tuples is expensive

Okay, that's all fine but I'm still not sure what to use when. I see that most of the methods return a tuple but everywhere else Lists are used, and many methods accept Lists as input, not tuples. By the stated points above, shouldn't Tuples be used for passing data around, since reading from a tuple of user-given values would be fast?

I also noticed Tuples aren't enumerable, what's up with that? Wouldn't using Enum over them be faster than using it on Lists?

If someone could help me understand them better, possibly by giving a few examples of what to use when, that'd be awesome.

Elixir Solutions


Solution 1 - Elixir

You've already given a pretty good summary of the differences, so in any conditions where one of those things is important it should help you decide on which to use.

The way to think about it is that Lists are open-ended data structures and their size can vary at runtime while Tuples have a constant size set at compile time.

For example if you wanted to store all the commands the user has given during an iex session you would want a list - the length of that list will depend on the number of commands given in that session. Contrast this with a typical use-case for tuples - returning {:ok, result} or {:error, reason} from a method - here the number of elements is known up-front and so you don't pay an unacceptable price for the performance improvements of Tuples.

As for enumeration - Tuples conceptually aren't collections and every element's position is supposed to also denote its role. Consider an {:ok, #PID<0.336.0>} Tuple - iterating over it would first give you an :ok and then a #PID<0.336.0>, it would be very strange to write a function acting in a uniform way on those things.

Solution 2 - Elixir

I'm no expert but this is my understanding:

Under the hood, a list is a linked list. Hence it's got the performance characteristics of a linked list. That is, getting the length is O(n) because I have to walk the entire list. Likewise a list has the advantages of a linked list as well; that is, it's easy to grow it by adding to the front.

I'm not sure what a tuple is under the hood but I do know it's not a linked list. Someone asked about enumerating tuples on the Elixir language mailing list back in 2013 and this is part of the response:

> "Tuples also aren't meant to be iterated over, don't get confused by > the fact that you could using elem/2 and size/1. Tuples are for > storing multiple pieces of information together, which does not imply > that they are intended for storing a collection."

-- Peter Minten

> "Another explanation would be that tuples are poor man's records. In > other words, a tuple represents a single piece of data, a single > value, albeit aggregate. You cannot take away an element from a tuple > without changing the semantic meaning of that particular tuple value. > > "This is contrary to lists and other collections that store many > values independent values. Taking a value away from list simply > reduces the length of the list. It doesn't affect semantic meaning of > anything."

-- Alexei Sholik

In other words just because there's a superficial resemblance between tuples and lists one shouldn't assume the behavior is the same.

Solution 3 - Elixir

In addition to what already had been said, what helped me differentiate a tuple from the list is analogy to a row in a database. If you think of a tuple this way, it is easy to see how information within the tuple is related to each other and it also becomes obvious why you wouldn't use it as Enumerable.

Solution 4 - Elixir

If you're familiar with Java:

  • A list is like a LinkedList.
  • A tuple is like an ArrayList.

Solution 5 - Elixir

Tuples are meant to hold a fixed number of elements that's why they allocate memory upfront. Basically tuples are not meant to change (although it's possible but expensive). They provide one piece of related information.

For example: Geographical coordinates {43.258389, -2.924405}

Lists on the contrary are more suited for dynamic collections (they are cheaper to modify).

I found this post very useful: https://blog.appsignal.com/2018/08/21/elixir-alchemy-list-vs-tuples.html

Solution 6 - Elixir

Since someone mentioned that they're not sure what a tuple resembles under the hood, a tuple would be similar to an array since both an array and tuple store elements in contiguous memory. So, the same rules would follow with when you would use an array over a linked list as it would with a tuple over a list in Elixir.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSheharyarView Question on Stackoverflow
Solution 1 - ElixirPaweł ObrokView Answer on Stackoverflow
Solution 2 - ElixirOnorio CatenacciView Answer on Stackoverflow
Solution 3 - ElixirindykidView Answer on Stackoverflow
Solution 4 - ElixirtbodtView Answer on Stackoverflow
Solution 5 - ElixirAlex EpeldeView Answer on Stackoverflow
Solution 6 - ElixirAmit L.View Answer on Stackoverflow