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.
_______________________________________________
eeps mailing list
[email protected]
http://erlang.org/mailman/listinfo/eeps

Reply via email to