`is_empty` Guard for Binaries in Elixir

· 1 min read

tricks elixir hacking

I have many times heard the question โ€œHow would one implement is_empty guard for binaries in Elixir .โ€

It is impossible out of the box, basically because guards are compile-time beasts. The documentation on Guards states:

Guards are a way to augment pattern matching with more complex checks; they are allowed in a predefined set of constructs where pattern matching is allowed.

That said, one can not just put String.trim(s) == "" because call to String.trim is not allowed in guard:

iex|1 โ–ถ defmodule TestEmpty, do: def test(s) when String.trim(s) == "", do: :ok
** (CompileError) iex:1: cannot invoke remote function String.trim/1 inside guard

So far, so bad. But there is a nifty workaround: one might explicitly trim_leading the String with pattern match:

defmodule TestEmpty do
  def trimmer(<<" " :: binary, rest :: binary>>), do: trimmer(rest)

  def trimmer(string) when string == "",
    do: IO.puts "Empty input"
  def trimmer(string) when is_binary(string),
    do: IO.puts "Left trimmed string is: [#{string}]"
end

TestEmpty.trimmer "       "
#โ‡’ย Empty input
TestEmpty.trimmer "    โ˜†  "
#โ‡’ย Left trimmed string is: [โ˜†  ]

This approach wonโ€™t work if one needs to deal with the original input unless it is โ€œempty,โ€ but in most cases it would do the trick. After all, we for some reason already treat spaces as empties.