1

I have the following Elixir script:

a = [1, 2]
b = [a | 3]
IO.puts is_list(b)
IO.inspect b

I thought that my code b = [a | 3] was wrong and this would cause an error.

But when I run this script, I got this result:

true
[[1, 2] | 3]

What means the pipe character within the last line of output?

Tsutomu
  • 4,848
  • 1
  • 46
  • 68
  • 1
    Both answers below are correct, I would just put the answer on “how would I write this code to accomplish a task” here: `b = a ++ [3]`. – Aleksei Matiushkin Nov 10 '16 at 09:55
  • 1
    After reading PatNowak's answer, I realized my question was a duplicate of http://stackoverflow.com/questions/34784320/elixir-list-concatenation. It seems that it is a FAQ on Erlang/Elixir world. – Tsutomu Nov 10 '16 at 11:18

2 Answers2

4

The | character is called the cons operator and is for linking an elixir term to another elixir term to build linked lists. All "proper" lists end with the empty list like so: [1 | [2 | [ 3 | []]]] But you can actually end a list with any elixir term at which point it becomes an "improper" list, like so [1 | [2 | :three]]].

You are seeing that output instead of [[1,2],3] because your list is an "improper" list.

This is actually very useful output because in order to pattern match on it you'd have to use the same form. [[a,b] | c] would match where as [[a,b],c] would not.

greggreg
  • 11,945
  • 6
  • 37
  • 52
2

The | operator splits list into head and tail. Head is first element, tail is everything else in another list or just empty list.

Consider this:

a = [1, 2, 3]
a = [x | y] # x = 1, y = [2, 3]
hd(a) == x # true
tl(a) == y # true


b = [1]
b = [x | y] # x = 1, y = []
hd(b) # 1
tl(b) # []

When you have construct like [1, 3] it means this is improper list.

PatNowak
  • 5,721
  • 1
  • 25
  • 31