What is the return type of a tail-recursive function

zxq9 zxq9@REDACTED
Thu Feb 13 11:14:04 CET 2020


On 2020/02/13 15:21, by wrote:
> What is the return type of a tail-recursive function?

This is actually a more involved question than the way it was posed.

Briefly, it is whatever type is actually returned.

An infinite loop or loop-until-termination function would be typed as 
no_return() as mentioned already.

Consider a main loop or service loop:


   -spec loop(State) -> no_return()
       when State :: term().

   loop(State) ->
       receive
           {expected, Message} ->
               NewState = do_stuff(Message, State),
               loop(NewState);
           retire ->
               exit(normal)
       end.


A recursive function that has a clause that breaks the loop, however, 
will have a normal return type.

Consider a manually written "sum" function:


   -spec sum([number()]) -> number().
   % sum/2 actually *does* return though it is tail-recursive.

   sum(Numbers) ->
       sum(Numbers, 0).

   sum([H | T], A) ->
       sum(T, H + A);
   sum([], A) ->
       A.


If you have a function that *might* throw an exception then you 
disregard that possibility and type it the way it is coded.

Exceptions are EXCEPTIONAL and should not be used as a hacky way to 
achieve a non-local return.
Consider, for example, that every function ever written *might* return 
an exception, but we don't type every function as `some_type() | 
no_return()` do we?

-Craig


More information about the erlang-questions mailing list