Photo by Craig Garner on Unsplash

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"
true

And 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">>).
true

We 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
:ok

Pattern-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()
:ok
iex(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.)

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.