Unexpected tail value after destructuring List of integers in Elixir

89 views Asked by At
iex(1)> [foo|bar] = [2,3,4,5,6,7]
[2, 3, 4, 5, 6, 7]
iex(2)> foo
2
iex(3)> bar
[3, 4, 5, 6, 7]
iex(4)> [foo|bar] = [6,7,8]      
[6, 7, 8]
iex(5)> foo
6
iex(6)> bar
'\a\b'

I would have expected bar to be [7,8] in the end, however it has the value '\a\b'.

I'm new to Elixir and looking for an explanation why this is. I'm running Elixir 1.13.3.

1

There are 1 answers

0
Everett On BEST ANSWER

Your output actually IS [7, 8]... it's just been re-formatted.

This is perhaps one of the most confusing things in Elixir, but there is a historical reason for it. Pay close attention to the single quotes you see in the output: they indicate a charlist which is a list of unencoded codepoints (which are sort of old-Erlang versions of strings from a time when Erlang did not have built-in support for strings). Codepoints represent Unicode characters. Elixir is trying to offer some backwards compatibility with Erlang charlists by formatting lists as human-readable when its members consist of integers in the ASCII range. You can override this formatting behavior as an option for IO.inspect/2:

iex> IO.inspect([7, 8], charlists: :as_lists)
[7, 8]  # <--- there is your list!
'\a\b'  # <--- here is the attempt at making it human-readable

iex> IO.inspect('cat', charlists: :as_lists)
[99, 97, 116]
'cat'

This behavior only kicks in when the list contains integers in the ASCII range. No special options are necessary to customize the formatting when the members aren't in the ASCII range, e.g.

iex> IO.inspect([1001, 1002, 1003])
[1001, 1002, 1003]
[1001, 1002, 1003]