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

Loïc Hoguin essen@REDACTED
Wed Sep 12 10:30:44 CEST 2018


On 09/10/2018 04:37 PM, Fred Hebert wrote:
> It could make sense. I've just sent a PR on the EEP where I touch this a 
> bit; it's not a strong argument. There are two possible approach: 
> matching on all ok- and error-based tuples, or keeping the same exact 
> semantics although requiring the pattern to be explicit.
> 
> In the first case the question is if it would make sense to choose all 
> good values to be those in a tuple starting with |ok| (|ok | {ok, _} | 
> {ok, _, _} | ...|), and all error values all those starting with error 
> (|{error, _} | {error, _, _} | ...|).
> 
> This approach would allow more flexibility on possible error values, but 
> would make composition more difficult. Let's take the following three 
> function signatures as an example:
> 
> |-spec f() -> ok | {error, term()}. -spec g() -> {ok, term()} | {error, 
> term(), term()}. -spec h() -> {ok, term(), [warning()]} | {error, term()}. |
> 
> If a single |begin ... end| block calls to these as the potential return 
> value of a function, the caller now has to have the following type 
> specification:
> 
> |-spec caller() -> ok | {ok, term()} | {ok, term(), [warning()]} | 
> {error, term()} | {error, term(), term()}. |

Isn't that incorrect? There's no reason the spec for caller() would have 
all 3 'ok' in its type since the resulting type would be either the 
error tuples OR the result of the last expression in the begin..end 
block (which may or may not be the left hand side of a <~ expression).

So the spec for caller() would be:

-spec caller() -> OK | {error, term()} | {error, term(), term()}.

Where OK is whatever the last expression of the begin..end block is.

Somehow I do not see this as being a big problem, at least as far as 
specs go. There's very little code that's larger than a 3-tuple for 
error tuples, and even 3-tuples are not that common.

This would basically correspond to a case block where instead of 
matching on "{error, _}" and returning that, you would match on "Error 
when element(1, Error) =:= error".

Doesn't sound like this would have negative performance implications 
either, it may actually be faster since you don't need to check the 
tuple size.

This can be allowed regardless of the unwrapping done on ok tuples and 
whatever limitations they may have.

-- 
Loïc Hoguin
https://ninenines.eu



More information about the eeps mailing list