Are there any popular languages which don't have unchecked exceptions? Java, for example, supports both checked and unchecked exceptions. In practice, checked exceptions seem to cause more problems than they solve for large scale software development. If you want to inherit from a class or interface it becomes impossible to add new checked exceptions to method signatures. So developers have to resort to hacks like wrapping the new checked exception in an unchecked exception.
This is a pet peeve of mine, checked exceptions map one-to-one to Result types, and in my opinion the former is strictly better (it automatically unwraps the ok result on successful execution, while makes the error handling as tightly scoped as one wishes (try block, leaving it out and auto-bubbling up) with native language support. Plus it includes proper stack traces which are a must in production systems (as much as some people hate them).
Now don’t get me wrong, Java’s implementation leaves much to be desired, inheritance is not the correct choice for denoting it, but I feel we really didn’t give it a proper choice.
Neither Rust nor Go have exceptions at all, and I would consider them "popular" at thos point. To be fair, they each also make you think more about your error handling (there are multiple valid approaches in each language).
Rust does have a feature called "panics" that is similar to exceptions in other languages. A panic in Rust is an unrecoverable error that can occur at runtime. Unlike exceptions, however, panics are not caught automatically by the language runtime. Instead, panics are propagated up the call stack until they reach a "catch point", where they can be handled by the programmer.
1. An exception is a recoverable error, that's the entire point, that's what catching an exception is.
2. Unlike Go's, rust's panics do not actually, universally, get "propagated up the call stack until they reach a "catch point", where they can be handled by the programmer". There's a compiler flag which can be "unwind" or "abort". In the former case (the default), panics can be caught and recovered from. In the latter case, the program gets hard-stopped on the spot.
> Unlike Go's, rust's panics do not actually, universally, get "propagated up the call stack until they reach a "catch point", where they can be handled by the programmer". There's a compiler flag which can be "unwind" or "abort". In the former case (the default), panics can be caught and recovered from. In the latter case, the program gets hard-stopped on the spot.
There are Rust libraries (e.g. salsa, used in rust-analyzer itself) that use unwinding internally for non-local control flow and won't work with unwinding disabled.
2. In default Rust config, unhandled panics end up unwinding the stack, calling destructors for everything, freeing resources, closing files and sockets, and printing an error message and possibly a stack trace. I think this qualifies as the language runtime automatically catching the exceptions.
3. For 99% of users, panic = unwind in rust. If you play with compiler flags, C doesn't have undefined behaviour because ubsan will abort programs if you compile with the right flags.