[eeps] EEP 049: Value-Based Error Handling Mechanisms

Fred Hebert mononcqc@REDACTED
Tue Oct 13 15:42:04 CEST 2020


On Fri, Dec 7, 2018 at 6:28 AM Kenneth Lundin <kenneth@REDACTED> wrote:

> EEP-0049 Value-based Error handling mechanisms
>
>    - We don't like a language construct which is hard coded to support ok,{ok,Result},
>    {error,Reason}.
>    - the use of underscore _ <~ to mean a match with ok is not a hit, it
>    will make programs harder to read
>    - We are against the introduction of *unwrapexprs* that cannot be used
>    everywhere where expressions are allowed.
>    - The *unwrapexpr* changes the scoping rules and can not be used in
>    nested expressions and not outside begin ... end.
>
> It is perfectly possible to use throw and try catch to replace or simplify
> deeply-nested case ... end expressions in the same way as the proposed
> language extension does.
> ...
> Summary
>
>    - We say no to the proposed language extensions. We don't think they
>    are general enough and we also see some problems with them.
>    - The same effect can be achieved safely with the current language
>    using throw, try...catch.
>    - Encouraging ok, {ok,Result}, {error,Reason} as results from
>    functions can be done in other ways, for example through library functions.
>    These values should not be special to the *language*.
>    - We also want to thank the author for a very well thought through and
>    well documented proposal which has triggered us to think about possible
>    solutions in this area. We really appreciate the effort.
>
> /Kenneth, Erlang/OTP Ericsson
>
I'd like to come back and revisit this.

I won't re-expand on my disdain for try...catch based control-flow for
common cases, but I was wondering what would the opinion of the OTP team be
if I were to re-work the proposal towards a less *opinionated* approach to
this control flow, something possibly more in line with Elixir's with.

Currently the simplest way to transform this proposal is probably to allow
the pattern on the left-hand-side of <~ to be any pattern, and only escape
the begin...end construct as a short-circuit return:

begin
  {ok, X} = exp(), % hard crash if it doesn't match
  {ok, X} <~ exp(), % if it fails, begin...end returns the value of the
non-matching term
  ...
end

This gets rid of the _ <~ rhs() magic syntax, drops prescriptiveness of ok
| {ok, T} | {error, R} returns, but maintains high-level control flow that
doesn't risk transforming non-local returns into values (which forces
rewriting unrelated code to work nicely with high-level conditional flows
and clashes with value-based error handling) and establishing a sort of
conditional pipeline. It does lose some of the safety mentioned in the
original proposal, but we can't maintain that safety without normalizing
acceptable good or error values, which the OTP team has mentioned not
wanting to do at the language level.

Of course the logical expansion of it is going for:

case
 begin
  {ok, X} = exp(), % hard crash if it doesn't match
  {ok, Y} <~ exp(), % if it fails, begin...end returns the value of the
non-matching term
  ...
 end
of
  {ok, Good} -> ...;
  {error, Reason} -> ...;
end

which brings in whether a proposal rework that goes for something closer to
Elixir's with <https://www.openmymind.net/Elixirs-With-Statement/> would be
interesting.

Let me know if there's interest and I can rework things. I keep feeling the
pain of complex validation flows time and time again there, particularly
whenever there is one single good path and many bad paths possible for each
validation step.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/eeps/attachments/20201013/e7f2713d/attachment.htm>


More information about the eeps mailing list