Lists vs. Tuples - What to use and when?
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.
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.