# 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

Consider a main loop or service loop:

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

loop(State) ->
{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
```