I'm learning Erlang and trying to use Dialyzer to get maximum type-safety when it's possible. There's a thing that I don't understand: what is the type of non-terminating function and how to denote it in -spec
. Could anyone shed some light on this?
A function that loops forever and never terminates has the return type no_return()
. (That return type is also used for functions that always throw exceptions, e.g. a custom error function. If you don't specify that return type, Dialyzer will tell you that the function "has no local return".)
This is mentioned in the Types and Function Specifications chapter of the Erlang Reference Manual:
Some functions in Erlang are not meant to return; either because they define servers or because they are used to throw exceptions, as in the following function:
my_error(Err) -> erlang:throw({error, Err}).
For such functions, it is recommended to use the special
no_return()
type for their "return", through a contract of the following form:-spec my_error(term()) -> no_return().
no_return()
and none()
types in Dialyzer: joedevivo.com/2015/06/14/no-local-return.html –
Galliard The following examples are in Elixir, but I believe they make the use of no_return
and none
in typespecs clear for Erlangers too:
defmodule TypeSpecExamples do
@moduledoc """
Examples of typespecs using no_return and none.
"""
@spec forever :: no_return
def forever do
forever()
end
@spec only_for_side_effects :: no_return
def only_for_side_effects do
IO.puts "only_for_side_effects"
:useless_return_value # delete this line to return the value of the previous line
end
@spec print_dont_care :: no_return
def print_dont_care do
IO.puts("""
A no_return function that does not loop always returns a value, \
which can be anything, such as the atom #{only_for_side_effects()}
""")
end
@spec always_crash :: none
def always_crash do
raise "boom!"
end
@spec value_or_crash(boolean) :: number | none
def value_or_crash(b) do
if b do
1
else
raise "boom!"
end
end
end
© 2022 - 2024 — McMap. All rights reserved.