
TIL: Elixir Strings and Erlang Binaries
A string in Elixir are represented internally by binaries. We don’t use is_string/1, instead we use is_binary/1 for checks. In Erlang, it is worth noting that using double quotes to enclose a string is actually being referred to as a char list. Let’s see and try it out on iex:
iex(1)> is_binary("hello world")
true
iex(2)> is_list("hello world")
false
iex(3)> is_list('hello world') # note the single quotes
true
iex(4)> <<"some chars">> === "some chars"
trueAnd now, let’s try it out on erl:
1> is_list('some chars').
false
2> is_list("some chars").
true
3> is_binary("some chars").
false
4> is_binary('some chars').
false
5> is_binary(<<"some chars">>).
trueWe use <> to concatenate strings, its called binary concatenation operator:
iex> "Hello " <> "world" <> <<33>>
"Hello world!"iex> byte_size("Hello world!")
12
When concatenated to a null byte, binary concatenation operator exposes a string’s binary representation.
iex> "reveal me" <> <<0>>
<<114, 101, 118, 101, 97, 108, 32, 109, 101, 0>>We may also print the character representation of code points using IO.puts/1.
iex> IO.puts <<72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33>
Hello world
:okPattern-matching and destructuring a string is also possible:
iex)> << _ :: binary-size(6), rest :: binary >> = "Hello world!"
"Hello world!"
iex)> rest
"world!"A side note on Erlang interoperability
We don’t commonly use char lists in Elixir. But when talking to some Erlang libraries, many older libraries may not support binaries so we need to convert Elixir strings to char lists. Let’s try it out on Erlang’s HTTP client (httpc). Note that in Elixir, Erlang modules are represented in atoms:
iex(1)> :inets.start()
:okiex(2)> :httpc.request(:get, {'http://www.erlang.org', []}, [], [])
{:ok, ..}iex(3)> :httpc.request(:get, {"http://www.erlang.org", []}, [], [])
** (FunctionClauseError) no function clause matching in :string.substr2/2
(stdlib) string.erl:213: :string.substr2("http://www.erlang.org", 1)
(stdlib) string.erl:208: :string.substr/3
(inets) http_uri.erl:201: :http_uri.split_uri/5
(inets) http_uri.erl:137: :http_uri.parse_scheme/2
(inets) http_uri.erl:89: :http_uri.parse/2
(inets) httpc.erl:164: :httpc.request/5
(So next time you encounter a missing function or a library in Elixir, try and consult Erlang’s standard libraries.)
