Tuples versus improper lists

Hello,

in Erlang and Elixir, there are tuples like {a,b} and improper lists like [a|b] (improper because b is not a list).

From your experience, what are the advantages and disadvantages of using one or another, or is it indifferent?

When should one be preferred over the other?

Thanks,

The main difference IMHO is that tuple can have more than 2 values from which all will be O(1) to access. Other than that there isn’t much difference IMHO.

I would always prefer tuples unless I have explicit reason why not to do so (and then this reason should be documented).

3 Likes

The difference between tuples and lists is in performance characteristics, but also in conveyed semantics. Using the appropriate one makes code faster and, even more importantly in my opinion, more understandable in its intent.

I would say, tuples represent a bunch of terms that “belong together” but aren’t a collection, in the sense that you won’t iterate through them. An example is when returning multiple values from a function. Tuples are convenient and performant to pattern match, and convey the idea of a grouping of a specific small number of terms with definite positions that are just passed around together, but aren’t necessarily homogeneous.

Lists are enumerable collections of items. Although they can be used for the same cases described above, they tend to convey the idea of an ordered series of items, often homogeneous, that are worked on one by one.

EDIT: sorry, I overlooked that the question was specifically about improper lists vs. tuples

3 Likes

There’s very few situations where improper lists make sense. They’re well covered in the answers here:

4 Likes

Ah sorry, I overlooked that the question was specifically about improper lists.

As others said, I would not use improper lists unless there is a specific reason for it.

My argument would be again related mostly to conveying the right intent of some code. Tuples are the idiomatic (and efficient) way to pass around groups of terms. Improper lists would still look a lot like lists at a glance, and could easily be a source of confusion (or errors when trying to iterate them). Plus, it’s quite cumbersome to create and pattern match improper lists of more than 2 elements.

2-tuples and a single cons cell are generally the same. There’s a slight memory advantage to the list - it uses only 2 words, while a 2-tuple uses 3 (it also includes a header). In general, it doesn’t really make a difference, but it might in some high performance situations and also when implementing other data structures - I think array, gb_trees and HashSet all use cons cells in such a way to shave off some of the memory overhead.

7 Likes

I am getting the idea that cons cells (i.e., improper lists of two elements) are mostly only useful to replace 2-tuples inside modules implementing high performance data structures, and much nowhere else.

2 Likes

Another link I found related to this topic:

Functional Programming: what is an “improper list”?

1 Like