Earlier quoted context omitted.
Some people say the same about strong typing. Like, why do I have to write down the type of every single parameter or variable? Java is making me jump through hoops! The point is, if you don't need the rigor of a strongly typed compiled language, there are other languages you can use. Perhaps a bash script is all you need.
You are very confused... "strong" in strong typing doesn't mean you have to write much or at all. Actually, it doesn't mean anything really. But, let's say, Haskell is probably at least as "strongly typed" as Java -- at least that's how most people understand that wording. And you don't have to write types in Haskell at all. It will be a nightmare (as if Haskell can be anything else, but even by the very low Haskell…
Why checked exceptions failed
181–190 of 318 posts
Re: Why checked exceptions failed
#182Earlier quoted context omitted.
> write generic functions that take functions as arguments and re-throw the errors thrown by these functions There is a philosophy that applies here: simple things should be simple, complex things should be possible. The scenario you're mentioning is not common enough that the language design should be centered around it.
It's a very common pattern, almost every modern language has a "map" function. The map function can throw a superset of the exceptions that its argument can throw. If checked exceptions can't deal with this, they'll be of limited use.
Re: Why checked exceptions failed
#183Earlier quoted context omitted.
If it’s really recoverable, then should it actually be an exception? That's the problem with exceptions in general. They're a hammer that makes everything look like a nail. People start using them for all kinds of control flow situations because they're more convenient than having to deal with a lack of type system support for optional values, etc. You get to the point where you have a parser that is expecting a digi…
There are remarkably few situations involving recoverable errors, though, and they almost all look like "not found"--which includes your parse integer example--and, even then, most of the time you will want a forceful automatic exception variant and not a "recoverable" error value as there is almost never anything to do instead: try-parse is so rare of a thing that is correct to do it warrants having a quick "try" at…
For me it is much more ergonomic to use a
match tryparse somestring with
| Ok obj -> proceedFurther obj
| Error reasons -> handleerror reasons
For truly exceptional cases you don't expect to be recoverable? Yeah, throw an exception.Re: Why checked exceptions failed
#184Earlier quoted context omitted.
This comes from a misunderstanding of the reason why exceptions where designed they way they were. The whole point of exceptions bubbling up w/o having to write support code to deal with passing exceptions further is to make it so that the purpose of the function is clear to the reader. Go's exceptions have the same unfortunate property as Java's checked exception. And that's what makes Go's code atrocious. Every oth…
No. This comes from a misunderstanding of checked exceptions. Checked exceptions don't mean I need to handle the exception right now. They mean I need to either do that or declare throws. Declaring throws is fine it implicitly documents the code and enforces a similar requirement up the chain. Checked exceptions aren't the default and shouldn't be.
Re: Why checked exceptions failed
#185Earlier quoted context omitted.
Imagine that the functionality implemented by your method is very important. This functionality should not be needlessly aborted. If so you want to be aware of errors you can recover from, correct? This is why checked exceptions are helpful. It gives you a guaranteed-by-compiler list of exceptions and you can decide which of those you should recover from.
This is one of the main reasons why I personally try to avoid exceptions and instead encode failure into the type system. For example, returning a Result rather than just a 't. (You can refine the type further). Altough, in most languages that approach results in a lot of boilerplate. In F# it works quite well, though.
You can write almost exactly the same code with your Result by ignoring the error until the point you would catch it with exceptions.
The only difference is that exceptions bubble up if unhandled, which requires a generic catch to match code ignoring errors otherwise.
Re: Why checked exceptions failed
#186Earlier quoted context omitted.
No. This comes from a misunderstanding of checked exceptions. Checked exceptions don't mean I need to handle the exception right now. They mean I need to either do that or declare throws. Declaring throws is fine it implicitly documents the code and enforces a similar requirement up the chain. Checked exceptions aren't the default and shouldn't be.
Checked exceptions should be the default, exceptions should just be rare. They are overused in almost all languages.
Re: Why checked exceptions failed
#187Earlier quoted context omitted.
> The list of recoverable exceptions that can be thrown by a method should be part of the contract. If it’s really recoverable, then should it actually be an exception? How often do you see exceptions that are recoverable? > If not, then to avoid crashing you would have to catch the root Exception class, which everyone agrees is a bad idea. I disagree that it’s a bad idea, having a catch-all exception handler to avoi…
Yes, in Java’s parlance an Exception is a recoverable code path, Error is the kind that is not. E.g. a network call failing due to some IOException can be easily retried, that’s a proper error handling.
Re: Why checked exceptions failed
#188Earlier quoted context omitted.
Any chance you have a code/pseudo code example of this? My naive take on this would be “just use raii/closable”. (But easily and likely, I misunderstood)
Let's say Java had no checked exceptions. I could just write IO code without doing a try since no one is forcing me to check anything. But let's go further. Let's say I have an API x(). This API accesses my database as part of a larger transaction. I invoke x() and it fails with an SQLException which is declared. I can revert the transaction or I can choose to retry x(). The checked exception notifies me that there's…
That will be part of lib documentation, which should be read & understood regardless of existence of checked exception.
Re: Why checked exceptions failed
#189Earlier quoted context omitted.
It's a very common pattern, almost every modern language has a "map" function. The map function can throw a superset of the exceptions that its argument can throw. If checked exceptions can't deal with this, they'll be of limited use.
In the case of map function hopefully you're using it with methods that don't fail in serious ways, and don't need strong error recovery. If so Java has RuntimeException to handle that case. If serious errors are possible and strong error recovery is needed, then you need to avoid the conveniences offered by functional style programming.
... so the basic "catch" syntax starts to fall apart because now you have to catch everything and resort to stuff like Guava's Throwables helpers.
It's madness.
The problem ultimately is variance: Methods are covariant, but throws clauses must be contravariant.
There are ways to solve this but "checked exceptions" (as in Java) are not the right way. Ask anyone who's worked in Scala on the JVM which they prefer and you'll have your answer.
Re: Why checked exceptions failed
#190Earlier quoted context omitted.
> Let's say that the creator of the interface allows IOException, but the backend of my implementation is a database so I have SQLExceptions, same issue. The creator of the interface should decide on a generic exception type: public interface UniversalStorageInterface { void store() throws StorageException; } Then, in the present, the FileStorage can define (and throw) a FileStorageException (inherits from StorageExc…
So now whoever creates the interface needs to define an exception type per method, and whoever implements the interface needs to define a subclass of that per method and catch-and-wrap every exception their callee raises. You better add some serious tooling built into the language to facilitate this, because from experience ain't no way anyone's going to bother with this if they have to handroll it, even with IDE cod…