String.Chars for lists is implemented to consider the lists as a list of unicode code points.
The 87 represents the W you see represents the at the beginning of the line, the 13 (Carraige return) causes that it is printed at the beginning of the line.
23, 6, 3, 2, and 1 are some other kind of control characters, usually ignored by modern terminals.
If you want to see the list you need to use inspect, within the interpolation, eg. IO.puts("l1: #{inspect(l1)}").
I’ve been burned by this before. I wish the behavior can be changed slightly so that it only prints the string if every character is a printable character instead of any character is printable.
A slightly less verbose and very debug-friendly command I find myself using all the time: IO.inspect(l1, label: "l1") (will print l1: [23, 13, 6, 3, 87, 2, 1]).
you don’t have to remember to inspect in your string interpolation
it returns the inspected value as well, so you can easily pipe it anywhere in your code