Handling :undefined from Erlang

Erlang often uses :undefined instead of :nil (and by often, I mean I haven’t really seen an erlang source that uses :nil). Does anyone have any tips or pointers for avoiding erroneously matching :nil when :undefined should have been matched? Does dialyzer help with this?

Dialyzer can help to see those errors before hand, but only if it is configured correctly.

Personally I think, that carefully studying the described API and return values and code according to those described API is much more important than relying on external tools. If you want to avoid that problem for a certain function once and for all, just write a wrapper like this:

def f(a, b, c) do
  case :erlang_module.f(b, c, a) do
    :undefined -> nil
    result     -> result
  end
end

Testing can help to find those pretty good as well.

Basically this. It may be “inconvenient” but the documentation is upfront about the types - including what is returned. Example: :ets.info/1

info(Tab) -> InfoList | undefined

Types

Tab = tab()`
InfoList = [InfoTuple]
InfoTuple = 
     {compressed, boolean()} |
     {heir, pid() | none} |
     {keypos, integer() >= 1} |
     {memory, integer() >= 0} |
     {name, atom()} |
     {named_table, boolean()} |
     {node, node()} |
     {owner, pid()} |
     {protection, access()} |
     {size, integer() >= 0} |
     {type, type()} |
     {write_concurrency, boolean()} |
     {read_concurrency, boolean()}

Returns information about table Tab as a list of tuples. If Tab has the correct type for a table identifier, but does not refer to an existing ETS table, undefined is returned. If Tab is not of the correct type, a badarg exception is raised.

No, Erlang does not use :nil at all. Seeing everything always has a value we went for not having anything which could be interpreted as not having a value. I would interpret undefined as meaning the thing you are try to look at as not being defined. As for example the :ets.info/1 call where it means the table is not defined or in :erlang.whereis/1 where it means that the registered name is not defined.

2 Likes