How to print a list in the Linux terminal?

I am following the official Elixir guide. I am currently on the chapter “9. Recursion” and things are going relatively well.

However, I was trying to run the double_each example (it’s almost at the end) not in iex but in the terminal via elixir double_each.exs.

The code is:

defmodule Math do
  def double_each([head | tail]) do
    [head * 2 | double_each(tail)]
  end

  def double_each([]) do
    []
  end
end

Math.double_each([3,4,5])
|> to_string
|> IO.puts

But the output is just an empty line.

When I tried to modify the code to this:

defmodule Math do
  def double_each([head | tail]) do
    [head * 2 | double_each(tail)]
  end

  def double_each([]) do
    []
  end
end

Math.double_each([3,4,5])
|> to_string
|> IO.inspect

I got <<6, 8, 10>> as the output in the terminal.

Is it possible to somehow convert the output so it can be printed out via IO.puts?

Thank you in advance.

1 Like

Hi, welcome to the forum!

You’re hitting a common issue with lists of integers being printed as strings. Please have a look at this link.

Your code works as expected. Try this:

Math.double_each([1000, 2000, 3000]) |> IO.inspect()
2 Likes

Also note that:

  • IO.puts can only print things that implement the String.Chars protocol; for example, you can’t IO.puts(%{my: "map"}),
  • inspect function can turn anything into a string,
  • IO.inspect(foo) is basically IO.puts(inspect(foo)).
3 Likes

To add to @stefanchrobot’s great replies, inspect is how you print any Elixir data structure according to its Elixir presentation. “puts” is about writing whatever bytes you have to the console. So puts [6, 8, 10] will write down those bytes, which may not actually be anything readable in the terminal.

2 Likes

In addition to both answers, if you ever find out that you are inspecting a list, and you are getting letters,
such as in:

iex(14)> IO.inspect([65, 66, 67])                            
'ABC'
'ABC'

That is because the list is a printable list.

iex(15)> List.ascii_printable?([65, 66, 67])
true

iex(16)> [65, 66, 67]
'ABC'

IEx will interpret it as a charlist that is printable, same as if you write it,

iex(16)> [65, 66, 67]
'ABC'
iex(17)> 'ABC'
'ABC'
iex(18)> 'ABC' == [65, 66, 67]
true

So if you want to see the contents of the lists as integers, you need to pass this option to IO.inspect:

iex(19)> IO.inspect([65, 66, 67], charlists: :as_lists)
[65, 66, 67]
'ABC'

This is IMHO opinion the most asked beginner’s question, and you eventually you will be hit by it, and this, “This is an Elixir bug”, but it is not, it is a design feature.

1 Like