Why Can't Append 2 Lists?

Hi

Why can i do this:

iex> [1, 2, 3 | [4, 5, 6]]
[1, 2, 3, 4, 5, 6]

but not this?

iex> [1, 2, 3] | [4, 5, 6]
** (CompileError) iex:78: undefined function |/2

I don’t even understand the first form. It seems to mean a list embedded in a list, but the output is not a list embedded in a list-- it’s just a single list.

Kernel.++/2 is the concatenation operator.

[1, 2, 3 | [4, 5, 6]] is interpreted as [1|[2|[3|[4, 5, 6]]]] (or more accurately as [1|[2|[3|[4|[5|[6|[]]]]]]] as pointed out by @OvermindDL1)

Embedding the list is simply [1, 2, 3, [4, 5, 6]]

List module.

When order is important, lists are often assembled by cons-ing new elements as heads onto the existing list in reverse order and then Enum.reverse/1 is used to restore the intended order.

Other typical challenges for Elixir newcomers are recursion, pattern matching and concurrency (I think higher order functions should be in there as well) - and finally OTP.

A list on the BEAM is made up of cons cells. Think of a cons cell as just a 2-tuple but of the format of [left | right].

[1, 2, 3] == [1 | [2 | [3 | []]]]
tl([1 | 2]) == 2 # An 'improper list', but a perfectly valid cons cell

And yep, as @peerreynders said the ++ operator is the append 2 lists operator. Do note that is not a fast operation as it has to entirely rebuild the left list to concat them (I.E. it has to rebuild all the cons cells), which is fine if it is short.

Please consider the elixir doc and google are good resources for getting started

It is not just a single list, it is a linked list.

That is why You can pattern match with [head | tail]
That is why adding to the head is faster than adding to the end
And also why ++ is slow, as mentionned above

Welcome to functional programming :slight_smile:

1 Like

And also why ++ is slow, as mentionned above

Erlang -- The Seven Myths of Erlang Performance might be of interest (it’s not always slow).

Only slow if the left side is not short, as stated in my post. ^.^

3 Likes