3 ms·
> Exceptions aren’t “cleared,” they are “finally-d.” Because that’s how finally works This explains exceptions thrown in the try block, but what about exceptio
by dahart 5y ago
> Exceptions aren’t “cleared,” they are “finally-d.” Because that’s how finally works
This explains exceptions thrown in the try block, but what about exceptions thrown in the catch or finally blocks?
What is the reason for allowing returns in try-catch-finally blocks? Is there a good example of something that would be hard to handle otherwise? I feel like the article and examples here are all good demonstrations of why return statements should be avoided in try-catch-finally blocks.
- dvt 5y ago> What is the reason for allowing returns in try-catch-finally blocks? I think it just makes for a simpler language spec, and in this case, return is treated like any other statement; then again, there's a note here specifically about try-catch-finally blocks[1] so maybe it doesn't make for a simpler language spec :) [1] https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-return-statement https://tc39.es/ecma262/multipage/ecmascript-language-statem...
- dahart 5y agoYeah, that’s my thinking - it seems simple at first, but when you see that return and finally when used together are in conflict with their stated / expected behaviors and that the language specifies the tie breaker in a way that might be unexpected... wouldn’t it potentially be simpler both in the spec and to a developer to make return in try-catch-finally blocks a syntax error? I’m assuming there’s a reason to allow the return statements in try-catch-finally blocks, but I can’t think of a use-case. The only use for a return inside a finally block would be to cancel a return in a try or catch block, right? In what cases is that actually desirable? I can see wanting to return from catch, because something bad happened. Overriding that return in finally doesn’t make a lot of sense to me, but I’m certain the ES designers thought about it more than I did.
- jchw 5y agoI actually don’t think it’s to make the language simpler, but most likely for compatibility. First, Statement/Block are parameterized with whether or not they can contain Return statements in the spec, so it wouldn’t complicate the spec much. Second, it is exceedingly rare that JS compatibility breaks. The one recent break I am aware of is: var let = [] let[0] = 1 // Syntax error because let [ conflicts with destructuring lexical declaration.
- jwalton 5y ago> why return statements should be avoided in try-catch-finally blocks When I was a wee lad, learning basic and C, my father tried to impress upon me that a function should never have more than one `return` statement. Back in those days, all these languages had `goto` statements, and we were told never to use them, because they were bad. But goto isn't bad because "goto" is a bad word - it makes your life unnecessarily complicated. A goto makes it very hard to reason about code, because you never know how you got to a certain line of code. Line 21 comes after line 20, but it might also come after line 30 if line 30 has a `goto 21`. But, semantically, there's not a lot of difference between: int myfunc(int *ptr) { if (ptr == NULL) { return 1; } return 0; } and: int myfunc(int *ptr) { int result; if (ptr == NULL) { result = 1; goto END; } result = 0; END: return result; } When someone calls `myfunc`, and it returns, you don't know if it returned from the end of the function, or from the middle of the function. A function with multiple returns is a function full of gotos; or as my dad used to say: "Functions always have a single entry point; they should have a single exit point."
- RHSeeger 5y agoI've never been a fan of the "only one return" view. I find it far easier to understand when the "preconditions" are checked at the beginning of the function and, if they fail, bail out early (guard clauses). Then there's less mental load in the rest of the function.
- jwalton 5y agoI do this too. :P Especially in a language like Go or C where you don't have exceptions, I think the "fast fail" at the start of the function is a reasonable "exception to the rule". Otherwise you can quickly end up in a nested if statement hell. But back in the days when I was doing embedded work, I frequently came across problems where someone allocated some resource at the start of a function, freed the resource at the end of the function, but then either failed to realize there was a return in the middle of the function, or someone else came along later and added a return to the middle of the function; either way we ended up with a resource leak. I saw this pattern over and over again. "Fast fail" is reasonable design pattern, so long as it's at the top of the function and you're careful not to allocate things before you check for preconditions, but functions of the form: blah blah if blah blah return x else blah blah return y are (IMHO) an anti-pattern.
- masklinn 5y ago> What is the reason for allowing returns in try-catch-finally blocks? Disallowing them is more work. I don't dislike C# forbidding flow control in finally blocks, but I can well understand language designers not caring.
- mjevans 5y agoFrom an assembly focused point of view, multiple "return" functions executing is madness. Logically it makes far more sense for the flow of execution to be fully controlled by the return and absolutely depart the function. I now want languages who's spec allows this insanity to have a sanitizer like C#'s to prevent more footguns.