What is the best practice for matching function return values when the value isn't expected to be used?

As I run dialyzer on my code, I see instances of the following warning:

Expression produces a value of type 'ok' | {'error',_}, but this value is unmatched

I often execute functions in my code in which I don’t use the return value. An instance like this my be in a GenServer when I log a message from a downed task.

def handle_info({:DOWN, ref, _proc, _pid, reason}, state) do
  Process.demonitor(ref)
  Logger.warn "#{__MODULE__} Task failed expectedly: #{inspect(reason)}"
  {:noreply, state}
end

Dialyzer will complain that Process.demonitor/1 and Logger.warn/2 are unmatched. So I might change my code to the following:

def handle_info({:DOWN, ref, _proc, _pid, reason}, state) do
  _bool = Process.demonitor(ref)
  :ok = Logger.warn "#{__MODULE__} Task failed expectedly: #{inspect(reason)}"
  {:noreply, state}
end

However, now if Logger returns {:error, any} it could crash my server.

So I’m curious, what is the best practice for matching function return values when the value isn’t expected to be used?

Well, you already did the verbose way in _bool = Processs.demonitor(ref), a instead of prefixing a name by _, you can use _ alone, eg: _ = Process.demonitor(ref).

And yes, _ = f.() is the idiomatic way to say “I do not care for fs return value, but call it solely for its sideeffects.”

3 Likes