-
-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Composing errors is difficult #362
Comments
Here's a real-world example: I'm writing some code to control my ventilation system. This involves parsing some JSON configuration and turning that into Inko objects. A snippet of this code is as follows:
Here Of course in this case I can change
|
Actually with
I considered it in the past but wasn't sure about this, but perhaps we should ditch error types and just make
Turns into something like this:
This would then let us write this:
|
https://datavirke.dk/posts/fallible-missing-rust-error-handling/ is worth reading. |
Some additional thoughts on this: It's not uncommon to have a method that may produce an error, but no OK value. The simplest example is a method that validates some input, throws if it's invalid, and does nothing in particular when it's valid. With throws one would type such a method as For iterators we have a somewhat opposite problem: throwing makes it impossible to map an iterator that throws |
Worth reading: https://sabrinajewson.org/blog/errors |
Worth adding: for the case of |
Another article worth reading: https://sled.rs/errors |
Consider a method like this:
In some cases we may want to map the error into say an
Option
, like so:This doesn't work because the return type of
foo
isSomeValue
, but the return type of theelse
isOption
. Something like this doesn't work either, becausetry
only applies to/works for method calls:This won't work either:
To work around this you have to introduce an auxiliary method like so:
A generic version would be this:
This could be turned into something like this:
While this works, I'm not sure I'm a fan of this approach.
An area where this doesn't report is when dealing with iterators:
If you have an iterator that doesn't throw, using a method that throws in e.g.
map
isn't possible:This won't work because the iterator is typed as
Iter[Int, Never]
, meaningmap
can't throw. This in turn means it's practically impossible to use methods that throw inside iterators, and you just want to re-throw the error.This is also true for Rust: if you use e.g.
for_each
you can't bubble up aResult
, instead you have to usefor
. Inko used to havefor
but I removed it as the implementation was a bit messy. While it's one way to handle things, I'm not sure I'm a fan of relying on dedicated expressions just to make it easier to bubble up errors.Inko needs to provide a solid answer to this.
The text was updated successfully, but these errors were encountered: