[eeps] EEP ???: Value-Based Error Handling Mechanisms
Fred Hebert
mononcqc@REDACTED
Wed Oct 3 04:27:02 CEST 2018
On 10/02, Raimo Niskanen wrote:
>I somehow feel a need to be able to distinguish between ok and {ok,_}.
>
>In your example for Reducing Nesting, Mnesia, the
>
> _ <~ disk_log:sync(...)
>
>is not exactly equivalent to
>
> case disk_log:sync(...) of
> ok -> this;
> {error,Reason} -> that
> end
>
>since if disk_log:sync/1 would return {ok,_} that would be allowed after
>the rewrite to use <~ but case clause before.
>
That is correct. In the case of `_ <~ Exp` the more equivalent match
expression would be:
case disk_log:sync(...) of
ok -> this;
{ok, _} -> this;
{error,Reason} -> that
end
>I think being able to narrow possibilities in the code is a good thing, but
>I have not found a good way to squeeze it into this language extension.
>But I would like to be able to somehow specify to allow ok but not {ok,_}
>as a success value...
Essentially, a flat `ok` is made similar to `{ok, <null>}` by the
pattern: it is really trying to say "unpack the good value", whatever it
is.
You can allow `{ok, _}` but not `ok` by matching on `_Ignored <~ Exp`
since that binds a variable and 'ok' can't make that possible, but there
is indeed no way to say "I need this to be `ok` with no actual value
bound and also make sure nothing is returned aside from ok". This one
specific case would require you to use a case expression as you
currently would today.
To make a distinction between these, I think would involve one of the
following:
- ask for an explicit pattern (`{ok, _} <~ Exp` vs. `_ <~ Exp`, which
means you can create invalid syntactic cases by using `{error, _} <~
Exp`)
- allow the `<-` operator for exact matches (contains the caveats
explained in earlier posts)
- introduce some prefix operator
- introduce a new kind of pattern to mean "No value returned", which is
basically a terrible idea for a functional language IMO.
I don't think any of these are nice enough either, at least compared to
the convenience of being able to handle `ok` as a positive return value
in general. Might as well use a case expression for these.
The problem goes away entirely if `ok` is not possible to use with the
construct (you have to extract a value), but my guess is that this would
instead encourage people in the community to use `{ok, undefined}` as
return values to fit with nicer workflows.
A quick search yields 17 functions in all of OTP that currently use this
possible return value in a signature:
$ ack -r '[^{]ok.*\|.*{ok,' | grep '\.erl' | wc -l
17
2 of them are in test suites, at least 5 of them are using signatures
with over 3 variants of `ok | {ok, _} | {ok, _, _} | {ok, _, _, _}`
which wouldn't work anyway, and one of them is a false positive on the
regex.
Of the 11 left, the most notable one is possibly ssl:close/2 (and ~3-4
variants) where the function can be used both to close the socket and to
downgrade it to a non-ssl connection. I would argue that the proper
thing would have been to have a 'downgrade' function, but this isn't
what's at stake here.
In any case, the pattern is likely rare in terms of possible producing
sites, but I couldn't say how it goes as far as call-sites are
concerned.
>
>An interesting EEP. A bit over-magical as Adam Lindberg thought - the
>relation to {ok,_} and {error,_} feels rather hidden in the <~ operator.
>But I do not have a better suggestion. :-/
>
Alright. Is this basically the EEP being turned down, or more of a
general remark, though?
I'm curious what the next steps are. If the overall feeling is "nice but
not nice enough", I'd rather see the EEP rejected than left to linger
for many years, as seems to be the case with multiple EEPs in the past,
so at least I know where to stand.
More information about the eeps
mailing list