What is a proper list?

iex(1)> ioList1 = [0,1,[2,3,5],6|<<7>>] # last item is a binary string
[0, 1, [2, 3, 5], 6 | "\a"]
iex(2)> ioList2 = [0,1,[2,3,5],6|'7'] # last item is a char list
[0, 1, [2, 3, 5], 6, 55]
iex(3)> ioList3 = [0,1,[2,3,5],6|"7"] # last item is a string
[0, 1, [2, 3, 5], 6 | "7"]
iex(4)> ioList4 = [0,1,[2,3,5],6|[7]] # last item is a proper list
[0, 1, [2, 3, 5], 6, 7]
iex(5)> ioList5 = [0,1,[2,3,5],6|7]
[0, 1, [2, 3, 5], 6 | 7]
iex(6)> :erlang.iolist_to_binary(ioList1)
<<0, 1, 2, 3, 5, 6, 7>>
iex(7)> :erlang.iolist_to_binary(ioList2) 
<<0, 1, 2, 3, 5, 6, 55>>
iex(8)> :erlang.iolist_to_binary(ioList3) 
<<0, 1, 2, 3, 5, 6, 55>>
iex(9)> :erlang.iolist_to_binary(ioList4) 
<<0, 1, 2, 3, 5, 6, 7>>
iex(10)> :erlang.iolist_to_binary(ioList5) 
** (ArgumentError) argument error
    :erlang.iolist_to_binary([0, 1, [2, 3, 5], 6 | 7])

Seems an IO List needs a “list-like” item (binary, char list, string or proper list) in the final position.

1 Like

iolists allow you to append things to the end of a list in O(1) because you are not building a proper list. But it depends on you having to convert the iolist to either a proper list or binary at the end. It is more efficient.

The type definition (in erlang) for iolists is maybe_improper_list(byte() | binary() | iolist(), binary() | []).

Btw the nil in the internal erlang terminology is very old and comes from lisp. We also called the lists cells for cons cells. I still do sometimes. :smile:

EDIT: in that sense the internal nil has nothing to do with elixir nil. There is no equivalent internally to null or no value, everything has a value.

3 Likes

Yeah I still do, force of habit. ^.^

1 Like