thanks for this reply, it's super informative! I've done a fair amount of ocaml programming but not as much as I would like with Core. Or_error looks really nice.
I think I underestimate the benefits that come with reducing the surprise in code. I get a similar amount of distaste lots of matching on option types and throwing to comparing to null and throwing. or_error definitely would help with that distaste I think.
you still have to give a lot of consideration to exactly what the error means, I think. in a lot of programs I write, the presence of an error cascades a lot and doing things like unwinding transactions and ensuring that the fault leaves a component in a consistent state is much more difficult than identifying all of the locations in a component where a failure could arise. maybe I'm doing something much higher level incorrectly but I've read a lot of other peoples code and it either has 10x the code to deal with, for example, many potential null-return scenarios or "works most of the time" and presents extremely critical consistency problems if a "stars align" error occurs ...
Yep, this is a hard problem. I wasn't super enthusiastic about the verbosity of option types when I first started programming OCaml, but almost two years later I'm quite convinced that they're the right way to do things. I really don't think there's a whole lot of downside, and being able to basically just not think about a large and hard-to-identify class of bugs is incredibly freeing.
This may not cover your use cases, but for cascading errors you can often write code something like the following:
match
foo_err ()
>>=? bar_err
>>=? baz_err
[... etc ...]
with
| Error e -> Log.error e
| Ok result ->
[...]
This ends up working pretty well when you're working with pure functions because there's not anything to unwind, but you're right that it doesn't solve all problems.
I'd just like to add that I definitely think I've seen the light and believe that this is the way forward, I just don't think that having nullable values is a dealbreaker when it comes to memory safety, because even if you don't have nullable values you still have huge problems to deal with in your code to make your system robust.
exception safety, maybe, but that's a superset of memory safety?
I think I underestimate the benefits that come with reducing the surprise in code. I get a similar amount of distaste lots of matching on option types and throwing to comparing to null and throwing. or_error definitely would help with that distaste I think.
you still have to give a lot of consideration to exactly what the error means, I think. in a lot of programs I write, the presence of an error cascades a lot and doing things like unwinding transactions and ensuring that the fault leaves a component in a consistent state is much more difficult than identifying all of the locations in a component where a failure could arise. maybe I'm doing something much higher level incorrectly but I've read a lot of other peoples code and it either has 10x the code to deal with, for example, many potential null-return scenarios or "works most of the time" and presents extremely critical consistency problems if a "stars align" error occurs ...