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. 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 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. 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.