6 ms·
We have it in Java too. For us it's try-with-resources and has nothing to do with checked exceptions. Checked exceptions remind you that you need to wrap the co
by invalidname 3y ago
We have it in Java too. For us it's try-with-resources and has nothing to do with checked exceptions. Checked exceptions remind you that you need to wrap the code and need to take that into account.
They also force you to declare that an exception is thrown if you don't want to handle it in the current method. That's important as the signature of the method carries an important failure that can't be dismissed and is enforced by the compiler.
- scarface_74 3y agoWhat “reminder” do you need to wrap your code? I can’t think of an instance that you wouldn’t wrap your code in a try/catch block around your code and either log and crash, log and continue, or for a specific exception that you know about, do “something”. But most of the time it’s the first two if you’re using RAII.
- invalidname 3y agoLet's say I write an API for handling IO. DB or File or networking or anything really. I get a failure, what do I do? I can throw an exception, but this is important how do I know the user of my API will actually do the cleanup after me. I can't do the cleanup since this is a part of an API not the actual usage of the API. How can I give the user of this API the right set of hint that "you need to pay attention to this" without worrying too much. Checked exceptions are that. A large part of the problem is when people use them for things that aren't important, but when they are important I can just declare a "throws" and know that someone will handle the exception along the chain. With runtime exceptions I have no guarantee.
- funnymony 3y agoAny 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)
- invalidname 3y agoLet'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 an important decision I need to make at this point, cleanup is one option but in some cases there are more. Furthermore, cleanup isn't always enough. In a case of an IOException I'd often want to notify the user e.g. if the disk is out of space I want to show an error message somewhere...
- funnymony 3y agoOn its own, seeing ‘SQLException‘ in method signature, does not provide you with information: “this is part of bigger transaction, and you have ability and responsibility to retry or rollback”. That will be part of lib documentation, which should be read & understood regardless of existence of checked exception.
- invalidname 3y agoNo. The transactional context is something the caller to the API knows. The person implementing the API that might fail on the SQL call doesn't know what's going on. That's why we would let the exception propagate. > That will be part of lib documentation, which should be read & understood regardless of existence of checked exception. First, checked exceptions *are* documentation for the lib. The best kind of documentation. Second, really? I would love to live in your world where people read documentation and where we all perfectly update the docs for everything. But both sides of this equation leave a lot to be desired in my world. I don't read the documentation of most changes to most libraries. If I did that I would never get anything done. I can't even keep up with every commit that goes into the project I'm running. There are too many changes and too much code (I'm talking 30+ non-trivial merges per day).
- scarface_74 3y ago> 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. Any decent C# linter will notice that the class exposes (IDisposable) and warn you that you should at least be wrapping it in a “using” block.
- funnymony 3y ago> important failure that can't be dismissed But importance of the failure is determined completely by the program, not the library. Grep fails to open a file for reading -> message the user and exit Nuclear reactor controller fails to read important a file -> initiate reactor shutdown or something. If file read is critical, you have to handle failure no matter what the interface is. Because you know that disk can fail.
- tremon 3y agoGrep fails to open a file for reading -> message the user and exit That should be: message the user and process the next file
- funnymony 3y ago:)
- MrJohz 3y agoBut the point is that in both cases the failure needs to be handled somewhere and somehow. Surfacing the error might be a valid option, but to make the decision you need to know that the error is there in the first place. This can be solved with good documentation, but it can also be solved in the type system. Typically, if I can get my computer to do work for me (e.g. make sure that I've handled all possible error cases) then I'm much more confident in my code, hence why I see a lot of value in a well-designed checked exceptions system.
- tadfisher 3y agoExceptions aren't normal parts of the type system though, they're a way to enforce control flow to deal with them. Another way to do this is with a Result type, which would actually be part of the same type system that you use in the rest of the language.
- MrJohz 3y agoWhy can't they be part of the type system? Rust is a good example of a case where they are part of the type system (albeit in a more monadic form). You've also got typed effects, where effects are essentially a generalised form of exception.