Reading @MRonErlang’s #book, and watching people struggle once more trying to explain catch
and throw
in Erlang… I came up with an idea …
Should we eventually true-up catch&throw?
The Problem
catch
and its friend throw
, were created to implement non-local return. That is, returning from a function before it’s done with its evaluation.
@MononcQc has probably the best explanation of it in LYSE, but the fact that he (and all of us trainers) needs to spend so much time teaching something that should be far simpler, it’s a symptom of the issue in general.
The Root Cause
I personally believe that, while throw
s, error
s and exit
s do have some things in common, conflating them into a single semantic category never really benefited any Erlang programmer. And it was surely detrimental to those (like myself) who came from other languages where throw
was clearly used to throw exceptions, not possible return values. For that, I expected to find something along the lines of return
(or ^
, in Smalltalk style).
The Proposed Solution
The Brutal Version
- Rename
throw
asreturn
. - Rename
catch
ashandle_return
(or something cleverer). - Stop handling errors with
handle_return
. The idea would be thathandle_return
will only handle… well… values returned fromreturn
. - Remove the ability to handle
throw
s fromtry…catch…after…end
. Or, alternatively, handle them as results, not as exceptions.
The More Amicable Version
- Add a new keyword
return
that works exactly likethrow
. - Add a new keyword
handle_return
(or something cleverer) that works likecatch
but it doesn’t turn errors or exits into tuples. - Do not adjust
try…catch…after…end
to handle these new returns within thecatch
part.- If we feel like we need to handle them somehow, make
handle_return
implicit intry
(i.e. as if everytry Expr…
would betry handle_return Expr
, thus returning the results as values).
- If we feel like we need to handle them somehow, make
- Slowly deprecate
catch
andthrow
over several OTP versions, recommending their replacement with the new keywords.- Or just deprecate
catch
making it evident thatthrow
does throw actual exceptions that can only be captured within atry…catch…
block.
- Or just deprecate