Hi Ben, 2014-05-26 17:13 GMT+02:00 Ben Millwood : > First of all, it seems to be universal among all languages I've much > experience with that there are unchecked exceptions. Your program might be > interrupted at any point by an out of memory error or a signal or > something, and there's just not much you can do about that. You can either > model it in your code or not, but you can't stop it from happening. So it > seems like the best we can hope for with typed exceptions is in addition to > unchecked ones, to make it possible (but not required) that a function > might declare some of the exceptions it can throw. > That's perfectly right. > > But after all exceptions are just "things I can return instead of a > result", and lightweight sum types are already pretty good at that. E.g. > (to use Romain's syntax) > > val lookup : map -> key -> value raise Not_found > > is pretty much just the same as: > > val lookup : map -> key -> value option > Right. This is a very good use case that I adopted thanks to core. > > True, exceptions get automatic propagation, but the option monad interface > makes that pretty lightweight, and you can do a similar thing with a less > trivial sum type if you need richer type information. > Using options or Result from time to time is certainly a nice habit. However to be honest, using option/result monads extensively does not seem right to me, like pulling the language in a direction it was not really designed for. Monad combinators do a great job at propagating errors, but still there is a serious addition of plumbing in function body's and Result returning functions have a significantly less readable type. But I guess this is pretty much a question of taste/habit to see if the added verbosity is worth it. > > See also: > https://blogs.janestreet.com/how-to-fail-introducing-or-error-dot-t/ for > discussions of more ways you can make error handling both explicit and > concise. > Thanks! BTW core still uses exceptions. Is there an explicit rule as to how to decide between Result type or exceptions. For instance, why not write the Array.create function like this: val create : int -> 'a -> 'a array Or_error.t where create fails for a negative integer?