Behavior of | with lists

iex(17)> mlist = [2,3,4]
[2, 3, 4]
iex(18)> new = [mylist | 7]
[[2, 3, 4] | 7]
iex(19)> new = [7 | mylist]
[7, 2, 3, 4]

Can someone help me understand why the different behavior in the two cases?

You should push from the head not the tail

this one is correct

[7 | mylist]

This one not, because You push a list from the left, intoâ€¦ 7

[mylist | 7]

In both (18) and (19) you are cons-ing a new head onto the list. In (18) the new head of the list is the â€śelementâ€ť â€ś`[2,3,4]`â€ť. In (19) the new head is the â€śelementâ€ť â€ś`7`â€ť.

1 Like

As a simple way to remember, a list can be decomposed as

where head is a single element, and tail is a list.

This way it is easy to remember that left side of | is an element, and right side is a list.

1 Like

Thank you for your quick response and the reference to cons, and the associated Elixir docs.

Thank you for your quick and helpful responses. Iâ€™m quite amazed by the helpfulness of the Elixir community.

Just a nitpick - strictly speaking it is a pattern match where `head` matches the head element while `tail` matches the remainder of the list. The big difference to a decomposition (or rather destructuring) is that pattern matching `[h|t]` cannot match `[]` while destructuring would simply set `h` and `t` to `nil`. Meanwhile a `[h|t]` pattern match will match a single element list by binding the single element to `h` and the empty list `[]` to `t`.

Pattern matching is a conditional construct and destructuring isnâ€™t.

It is true that my terminology is incorrect

I have been doing too much JS these days

I am still using destructuring while pattern matching should be used almost everywhere in Elixir

1 Like

As an additional note, the cons article mentions another useful list operator, append, which concatenates two lists. I see that ++ is Elixir for concatenating two lists, reference https://elixir-lang.org/getting-started/basic-types.html#linked-lists

iex(24)> [7 | mylist] = [7] ++ mylist
[7, 2, 3, 4]

In that context have a look at The Eight Myths of Erlang Performance: 4. Myth: Operator â€ś++â€ť is Always Bad.

i.e. be mindful of what you are doing when you are using `Kernel.++/2`