Java's distinction between Runtime and Checked Exception makes sense, and is pretty much the same panic vs Result distinction Rust makes. But Java's execution of the concept is terrible.

1. Checked exception don't integrate well with the type-system (especially generics) and functional programming. It's also incompatible with creating convenient helper functions, like Rust offers on Result.

2. Converting checked exceptions into runtime exception is extremely verbose, because Java made the assumption that the type of error distinguishes between these cases. While in reality errors usually start as expected in low-level functions, but become unexpected at a higher level. In Rust that's a simple `unwrap`/`expect`. Similarly converting a low level error type to a higher level error type is a simple `map_err`.

3. Propagation of checked exception is implicit, unlike `?` in Rust

Though Rust's implementation does have its weaknesses as well. I'd love the ability to use `Result<T, A | B>` instead of needing to define a new enum type.

I wish I could upvote this more. I can totally understand GP's sentiment, but we need to dispel the myth that results are just checked exceptions with better PR.

I think the first issue is the most important one, and this is not just an implementation issue. Java eschewed generics on its first few versions. This is understandable, because generics were quite a new concept back then, with the only mainstream languages implementing them then being Ada and C++ - and the C++ implementation was brand new (in 1991), and quite problematic - it wouldn't work for Java. That being said, this was a mistake in hindsight, and it contributed to a lot of pain down the road. In this case, Java wanted to have exception safety, but the only way they could implement this was as another language feature that cannot interact with anything else.

Without the composability provided by the type system, dealing with checked exceptions was always a pain, so most Java programmers just ended up wrapping them with runtime exceptions. Using checked exceptions "correctly" meant extremely verbose error handling with a crushing signal-to-noise ratio. Rust just does this more ergonomically (especially with crates like anyhow and thiserror).