5 ms·
I don't think I fully understand your comment. Regardless of whether I've read the whole program top-down, it is definitely easier for me to understand early-ex
by adamc 11y ago
I don't think I fully understand your comment. Regardless of whether I've read the whole program top-down, it is definitely easier for me to understand early-exit logic in a routine than to keep the mental stack of conditionals going, particularly when (as is often the case) the early exits consist of various deviations from the "main sequence" code (e.g., validations failing or other edge-cases).
- glastra 11y agoI was speaking from a general point of view. I find early exit on validation failure acceptable, although it'd make more sense to use exceptions and not a simple return. A sufficiently complex method with 5 return statements all scattered in between to treat real cases (i.e. not failures or conditions that should raise an exception) is certainly less readable than the same functionality refactored to a single return statement at the end with the proper use of branching. Aside from readability, it also increases maintainability. What if you have to introduce a modification to your logic that applies a transformation to the result? Should you modify it in 5 places, or 1?
- SideburnsOfDoom 11y ago> What if you have to introduce a modification to your logic that applies a transformation to the result? Should you modify it in 5 places, or 1? In 1 place, clearly. The multiple-return version would require a bit more refactoring at this point, either extracting another method or introducing the "return value" state var at that point. Why not code it with single return up front? Simple: most likely, You Aren't Going To Need It. The YAGNI principle says to make the code more complicated when you need to, not before.
- SideburnsOfDoom 11y ago> A sufficiently complex method with 5 return statements ... is certainly less readable than the ... single return statement at the end version In all cases? How can you even measure that? How can you do it in a way that's free of bias? If you've never used a style, of course you will find it harder. Dogmatic assertions that boil down to "what I'm used to is objectively better because of how it feels to me" are IMHO harmful.
- glastra 11y agoI cannot measure that on anyone else other than myself. This is a place to express opinion. I've read (and sadly written) enough code in both styles to know what _I_ (and all the peers I've bothered to ask with concrete examples, for that matter) find easier to understand, but there's of course all kinds of bias in there as well. Taking comments in HN as fact or truth is harmful, and (replying to your other comment) waving acronyms around is equally harmful, if not more. You can't possibly assert that writing code in one or another way is easier or harder, or that the code is "more complicated" (precisely what we don't seem to agree on). To be honest, I find it easier to write methods with single return statements (and exceptions to handle... well, exceptions[^1]). It all seems clearer in a "stream of thought" kind of way. Engrish is hard, sorry. [^1]: Early returns are exceptions for lazy coders.
- SideburnsOfDoom 11y ago> You can't possibly assert that writing code in one or another way is easier or harder In general, of course not. I think that both single-return and multiple-return styles can be valid and readable. But of course both can be obfuscated. But give me a particular piece of logic and I might give an opinion on which style I would use for it. & if you think YAGNI is harmful, you should see the pointless code from people who have never thought that way!
- conceit 11y agothe term callback hell comes to mind, although I'm not sure that's the entire problem you quoted
- SideburnsOfDoom 11y agoI wasn't talking about callback hell (1) but if you want to do so - the point is that if the "nested callbacks" style is objectively worse (and this seems likely) then this can actually be measured. Lines of code and cyclomatic complexity (2) is just the start. You would have to do something like ... e.g. take a group people skilled in some other programming language, give them a basic grounding in Javascript, and have them work with some JS code samples with and without nested callbacks. If there is clear difference in code comprehension, time to modify the code, lines of new code to accomplish a goal, and resulting bug count then you can have an informed opinion on if this code style is really objectively so bad. That seems like a costly and time-consuming procedure. But if some academic institution did this I'd be pleased - some scarce data and some actual science is IMHO is worth a thousand opinions in this kind of recurring stylistic debate. 1) http://callbackhell.com/ http://callbackhell.com/ 2) https://en.wikipedia.org/wiki/Cyclomatic_complexity https://en.wikipedia.org/wiki/Cyclomatic_complexity
- phamilton 11y ago"Oh... We call function foo. Let's go see what function foo returns. (Scroll to the end of the function)" With a single return, I can at least follow that thread fairly easily and sometimes it's just a few lines back in a large function. With many returns, I'm forced to start at the beginning of the function. There a dozen or so other culprits that make this difficult. Assignment in a block can be just as bad, for example, since I can't know which assignment occured without looking at all of them.
- SideburnsOfDoom 11y ago> sometimes it's just a few lines back in a large function Large functions that have both side effects and return values are themself the readability problem. Early return is not, it is a succinct way to express some functions with return values.
- glastra 11y agoExactly. See single return statement, highlight variable, see branch structure at a glance, ???, profit.
- Vaskivo 11y agoI disagree. The function signature should be explicit about what it does and returns. If it has a static/defined return type I know what I can expect from it. The function name should also be explicit about what it does and returns. Scrolling down to the end just to see a 'return books' statement is usually useless. If I need to read the whole function, I'd rather have early exits instead of nested ifs. It's easier to read because it follows the logic of "if (such and such condition): nothing else to do -> return;"
- camgunz 11y agoI like this ergonomics argument, particularly from a reader's perspective. But having had to read some single return value code recently, I found that the return value returned at the end of the function was rather unhelpful; it usually boiled down to "return rv;". I then had to go back up to the top of the function and follow through the nest of passed conditionals and side effects, fall throughs, and failed conditionals to see how "rv" was modified throughout the function. The non-linearity cost me a lot more thought, whereas with multiple return value code the failed conditionals are "tossed" out of my head very quickly. I think, given that you almost always end up reading the whole function anyway (which is probably good), linear is better than non-linear and consistency (bail early) is better than inconsistency (anything goes) when it comes to error handling.
- AlisdairO 11y agoCompletely agreed. I think early returns deep in the logic of a method can be problematic, but I think early returns at the top of a method before you get to the meat of the logic are very readable.