Java is the only language that I can think of that gets exceptions right, in that it forces you to acknowledge them every step in the chain and choose whether you're going to catch them or throw them upwards.
It is strange that the consensus in the Java community sort of ended up being against checked exceptions. I for one think that this consensus is completely wrong and I suspect that what looks like a consensus is just a bunch of very loud people shouting down everyone else (and to me not making very compelling arguments).
Elliotte Rusty Harold's brief post on this pretty much nails it for me:
http://cafe.elharo.com/blogroll/voting-for-checked-exception...
The problem is that it's a trade-off - it's not a case of one side being right or wrong. Checked exceptions introduce API fragility: when the implementation of a method changes in a seemingly inconsequential way (it may now throw an error), then all it's callers and all their callers, transitively need to have their signatures edited. What should be a simple matter between just the leaf method and the top-level now has to involve all the code between them, which may not even be in code you authored or controlled.
Unchecked exceptions, however, mean that code that would previously always succeed may now never even be executed. Which makes it difficult to reason about the behavior of your function.
It's the same trade-off that appears in several other areas of language design. Do you force developers to write down their assumptions in the source code, so that everyone reading it knows exactly what's going on? Or do you let them keep it in their heads, so that it can change easily when the system requirements change? Dynamic vs. static typing, global variables vs. parameters, polymorphism vs. conditionals, default arguments vs. explicitly specifying parameters - it's all the same fundamental argument applied to different language constructs.
Which side your on usually ends up depending on whether you read more code or write more code. Maintenance devs always want things to be explicit, because it makes it easier for them to grok the whole codebase and make the change they need to do. Green-field innovators always want things to be implicit, because it means they have to specify less, and everything they specify tends to end up changing anyways. Sometimes the same person ends up cursing both ends of the divide depending on what they happen to be doing at the time. I do a bunch of speculative prototyping for Search Features at Google; in this role, 90% of my code never sees the light of day, and so I write it with tools like Python or JQuery that let me easily change things around and not specify too many of the details. I also do a fair bit of infrastructure work on the search stack; in this role, I write barely any code and spend the bulk of my time tracking down where an obscure piece of data is coming from and how it needs to be modified to add a new feature.
It is a trade-off, on that I agree with you and I do understand that checked exceptions do tend to propagate implementation-level details up where that might be undesirable. I also agree that in green-field situations it can be awkward figuring out what to do with an IOException that you suspect will not exist in a few hours.
The problem as I see it is that if you advocate the alleged consensus that checked exceptions are evil then you are taking the position that there is no trade-off. Checked-exception lovers like myself acknowledge this grey area and the design challenges it presents. That is a big part of why I believe that a Java with checked exceptions is more "reality-based" than one without them, it recognizes the challenge and gives an API designer the tools to do the right thing. I want to have that hammer in my tool chest instead of banging on things with the back of my hatchet.
That's interesting. I'm not a day to day Java programmer so my perspective is different from the Java community's. I have ran into problems numerous times in other languages where an exception isn't discovered until runtime in production because there's simply no way of knowing whether a library's function might throw an exception or not. The workaround is to be overprotective. I've always envied that Java devs know what to expect from every function they call
Haskell does this also, and its type system is much more expressive than Java’s, enough so that exceptions are not (exclusively) a built-in language feature.