Using Enum.map on a list when adding 100 results in 'ihgfe'

result = Enum.map [5,4,3,2,1], fn(val) -> 
		  val + 100
            end

IO.inspect result # 'ihgfe'

If I want to add 100 to each item in the list what is the preferred way? I want to circumvent these kinds of issues altogether as much as possible.

This is down to how charlists work in Elixir/Erlang. If the elements of the list map to ascii characters it’s printed as a string. The values are correct, you can add an option to inspect to print as list e.g.

iex(1)> IO.inspect [101, 102, 103, 104, 105]
'efghi'
'efghi'
iex(2)> IO.inspect [101, 102, 103, 104, 105], charlists: :as_lists
[101, 102, 103, 104, 105]

Thanks for trying to explain this but…
If I have my previous code and I want to do something with the result it’s still a string and is useless.

result = Enum.map [5,4,3,2,1], fn(val) -> 
		  val + 100
         end

IO.inspect result # __________________'ihgfe'

new_variable = result + 100 # _________error

IO.inspect new_variable # ____________bad argument in arithmetic expression

You’re adding 100 to a list here, i.e. [1, 2, 3, 4, 5] + 100 which isn’t going to work

You are trying to add 100 to [101, 102, 103, 104, 105] - which doesn’t work, because you can’t add an integer to a list.

You are (rightly) confused because IEx prints your list as 'ihgfe' - note the single quote, this is still a list - if it was a string it would be "ihgfe" (note, double quotes).

iex(1)> 'ihgfe' === [105,104,103,102,101]
true

As you can see, both are the same, exactly the same, and you can still use 'ihgfe' as a list or as an enum, boths modules function does accept it.

Your problem in your codesnippet that causes the arithmetic error is something else:

You are trying to apply Kernel.+/2 to a list and a number, but it needs a number on both sides.

You simply can’t do [105,104,103,102,101] + 100, propably its Enum.map([105,104,103,102,101], &(&1 + 100)) what you really intendet to do, and that will works as Enum.map('ihgfe', &(&1 + 100)) also.

Oops, I was attempting to add an item to the end of the list.

I’ll stop typing for now and just read all the answers a bit slower before I dig myself a hole.

Appending a single item to the end of a list is done by list ++ [item], but you should try to avoid that, since it needs to copy and traverse the complete list for this so this operation is O(n).

For short lists, this doesn’t matter. But as soon your lists get longer OR you append to a list recursively this really can eat your cycles! Especially the latter will result in quadratic runtime.

Lists in BEAM are implemented as linked lists, immutable and indestructive linked lists to be exact.

What does “indestructive” mean in this context? Tried Googling it, but nothing that looked relevant came up. I would guess something like “you can’t delete things out of them”, but that seems redundant with “immutable”…

You are right. That word is redundant. Dunno why I had initially added that.