4 ms·
FWIW I didn't particularly like the article, but I really liked your comment. I think "an exception is when code can no longer do any meaningful work" is a grea
by hn_throwaway_99 2y ago
FWIW I didn't particularly like the article, but I really liked your comment. I think "an exception is when code can no longer do any meaningful work" is a great definition, and also explains why flow control with exception handling works the way it does.
Obviously there are gray areas re what it is to mean "code can no longer do any meaningful work", which is why there are decisions to be made about when to throw an exception or when to do something else. Usually, though, that "something else" is to return an error sentinel value, most often null or similar (e.g. "undefined"). And then I think the reason it's sometimes a tough call is that since null/undefined essentially means "empty", the APIs that most often return null do so in cases where you're asking for something and it's not there, so returning "empty" feels reasonable.
- wvenable 2y agoIn .NET, they have 2 sets of parsing functions, "Parse" and "TryParse" for parsing strings into other types. The first throws an exception if it can't parse and the second returns a Boolean indicating success or failure. Which function of these you use as a programmer is dependent on the context and it indicates your expectation. You might use "Parse" if you reading a well-defined file format where the string will always contain an integer and if it doesn't then something has gone horribly wrong. But you might use "TryParse" on user input where getting a non-integer is expected and you'll have to something about that other than error out.
- erik_seaberg 2y agoWas this a workaround for frequent exception handling being too expensive on some platform? I like how Java lets some exception instances be reused without stack frames, so performance issues are less likely to compromise API design.
- wvenable 2y agoSemantically I think it's great. .NET has a bunch of these especially in LINQ. A parsing failure isn't necessary an error. Sometimes it is, sometimes it's not. Even if exceptions weren't expensive, catching exceptions on all parsing (as you would in Java) is just ugly and, I would argue, not semantically correct. In my opinion, one should throw often but catch infrequently. Most of my large applications have a very small number of catches. It's also perfectly reasonable to move this down a layer and have Parse return an Option type and choose to handle did-not-parse case or don't and let that trigger an exception.
- jkrejcha 2y agoIt, according to Eric Lippert, was at least partially to fix the problem of vexing exceptions[1] that plagued Int32.Parse. Parse was first and it was kind of an unfortunate design decision to make a almost expected result (parsing to fail) throw an exception. It's worth noting that nowadays Parse is just a wrapper around TryParse that throws (although this is an implementation detail) [1]: https://ericlippert.com/2008/09/10/vexing-exceptions/ https://ericlippert.com/2008/09/10/vexing-exceptions/
- winstonewert 2y agoI think the causation runs in the opposite direction. These exceptions for these platforms were implemented in an inefficient fashion BECAUSE they thought that exceptions should almost never be thrown.
- lelanthran 2y ago> I think "an exception is when code can no longer do any meaningful work" is a great definition, I'm not so sure: that definition glibly turns every error or failure into an exception. Is "Failure to Open File" really an exceptional condition? This is a common condition that is basically a business rule[1]. Think about the "saving a file" action. There's errors that you expect to happen, and have to provide code to handle (like, permission denied, path exists and is a directory, etc), and exceptional conditions that should never have arisen in a program which no sane person would try to handle (Out of memory, disk write errors, etc). In both cases, no progress can be made and the callee has to return to the caller. But, in the error cases a well-written program will defend against the errors in a meaningful manner, whereas in the exceptional cases there is literally no point in putting in code to handle those cases. Just some food for thought - I'm not particularly married to these definitions. [1] Here are some hypothetical options for failing to open a file: 1. If the file doesn't exist, prompt the user asking if it must be created, and proceed only if "Yes" is received, return to caller if "No" is received. 2. If the file is a directory, display a fatal error message and return to caller. 3. If permission is denied, display an ACL error message and return to caller.
- wvenable 2y agoI have a desktop application with a single error handler at its event loop. All that handler does is show the exception message in a messagebox and then the event loop resumes. This application has a "save file" option. In this application it doesn't matter if the permission is denied, the path exists and is a directory, it was a network share that went away, or a disk write error, or out of memory, or a bug. If I press "Save" and the exception occurs, I can read the message and correct the problem if possible, and then just press Save again. It is incredibly robust and has effectively no error handling. Of course, that doesn't handle all the cases that you describe. For example, for your case #1 I think that isn't a case that no more meaningful work can be done and isn't an error. Instead, you're just asking a question and then proceeding or not based on the answer.