Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lists vs. Tuples - What to use and when?

Tags:

elixir

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.

like image 344
Sheharyar Avatar asked Jul 02 '15 19:07

Sheharyar


2 Answers

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.

like image 114
Paweł Obrok Avatar answered Nov 18 '22 09:11

Paweł Obrok


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.

like image 21
Onorio Catenacci Avatar answered Nov 18 '22 10:11

Onorio Catenacci