In Elixir, a range is a sequence of integers with a fixed step. The most common method of declaring a range is to use the x..y syntax. Enum is a collection of algorithms to work on enumerables. Enum.to_list converts an enumerable to a list.

Armed with that knowledge, review the following code and try to consider what the results should be.

Enum.to_list -1..10
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Hover to show

Enum.to_list 23..59
[23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59]
Hover to show

Enum.to_list 32..78
' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN'
Hover to show

Enum.to_list 79..129
[79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, ...]
Hover to show

Unless you already know where I'm going with this I bet you were surprised by the output of Enum.to_list 32..78. Why did the REPL spit back a bunch of characters when we defined a list of integers?

This happens because Elixir parses the resulting list as a charlist, a string-like remnant from Erlang:

A charlist is a list of integers where all the integers are valid code points.

Note that the above definition talks about ASCII code points, not Unicode. The first ASCII code point is 32 (' ') and the last ASCII code point is 126 ('~').

This is surprising behavior. I can see a situation where you debug a system, stepping through the stack, printing some suspicious variables. Suddenly you spot something that looks like a type error. The variable foo which should be a list of integers, looks like it's a string? But in fact, it's just a list of integers that all happen to be in the [32,126] range.

 > Enum.to_list 32..126
' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'
 > Enum.to_list 32..127
[32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, ...]
 > Enum.to_list 31..126
[31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, ...]

I imagine that, like Python's default dynamic parameters, this is just something that experienced Elixir programmers learn to distinguish. The single quotes are a tell-tale that the result is not a normal string, but a charlist. I guess it is also pretty easy to remember, given the very Wat-like experience when you see this occur for the first time.