unisonweb / unison

A friendly programming language from the future
https://unison-lang.org
Other
5.79k stars 270 forks source link

Make the nicely named functions use abilities rather than `Either` #1796

Open pchiusano opened 3 years ago

pchiusano commented 3 years ago

A lot of the IO functions can return failures and this is expressed using Either which leads to a lot of awkwardness.

First, a bit of renaming of abilities, let's distinguish between Throw, which is just early termination with a typed value (which might get used for control flow, like early termination from a deeply nested structure), and Exception, which is "something went wrong, here's a Failure":

ability Throw e where
  throw : e -> x

ability Exception where
  raise : Failure -> x

Next, go through the various IO functions that currently return Either, like:

openFile : Text -> FileMode ->{IO} Either Failure Handle

Suggestion is rename that to openFile.impl or similar, then in pure Unison (in IOSource.hs), define:

Exception.rethrow : Either Failure a ->{Exception} a
Exception.rethrow = cases
  Left e -> Exception.raise e
  Right a -> a

openFile : Text -> FileMode ->{IO, Exception} Handle
openFile fname mode = Exception.rethrow (openFile.impl fname mode)

And so on for all IO builtins.

It might be possible to do this programmatically by hooking into the builtin.merge command (consult @aryairani).

runarorama commented 3 years ago

This is a good idea.

aryairani commented 3 years ago

Is there value to having names exposed for both versions that outweighs the complexity? Or should we just switch to the new ones?

pchiusano commented 3 years ago

Having the .impl version just means you can implement the other in pure Unison code by referencing the foo.impl name in the definition of foo. You could deprecate / delete the .impl versions after that's done, or perhaps the tooling has a convention where it filters out .impl functions by default in various list / find commands.

It would also be a pain I think to have the builtin directly do Exception.

aryairani commented 3 years ago

I was implying not including a name for the .impl in the namespace, but I take it back. I think I'd just put the Exception versions in base (instead of derived functions in builtin; we can try to figure out how to auto-generate them though, if that would save work.

ceedubs commented 2 years ago

I think that for the most part this is the case now. @runarorama do you think that we are in a place where this could be closed out?

runarorama commented 2 years ago

There are still some places that use Either where they should use Exception