6 ms·
Could you please elaborate on No. 11? "Never use early exits". Could you please elaborate what you mean by that? PS. I'm not trying to unintentionally start a
by godbolev 14y ago
Could you please elaborate on No. 11?
"Never use early exits". Could you please elaborate what you mean by that?
PS. I'm not trying to unintentionally start a flame war. Just trying to understand.
- eranation 14y agoI'm glad you asked, I have the same question exactly.
- pestaa 14y agoI believe he referred to the rule to use a single return statement at the end of any single function definition.
- edw519 14y agoExcellent question that is difficult to answer. I'll give you a short response here and then write a blog post with example code when I have time. Put your email in your profile and I'll make sure to let you know when that's ready. A little background: I have gotten many calls when legacy code has a bug or needs a critical enhancement and no one in-house is willing or able to figure it out. I'm no smarter than anyone else, but because I'm stupid and fearless, I often do something that few others attempt: I rewrite or refactor the code first, then work on the bug/enhancement. And the first thing I always do is look for early exits. This has always given me the most bang for my buck in making unintelligible code understandable. The only entry to any function or subroutine should be on the first line and the only exit should be on the last line. This is never about what runs fastest or produces less lines of code. It's strictly about making life easier for the next programmer. Early exits can make things really easy (I'll just get out now.) 20 lines of clean code. No problem. Until years later, when that function is 300 lines long, and the next programmer can't figure out what you're doing. Much of the maintenance had been done in emergency mode, each programmer just trying to get in and out as fast as they could. Early exits make it much easier for bad things to evolve: - 200 line multiple nested if statements - 200 line multiple nested recursions - unidentified but critical "modes" (add/change) (found/notFound)... Removing early exits forces you to understand what really should be happening and enables you to structure code into smaller, more intelligible pieces. Short, hand-wavy response, but I hope that helps clarify some. Stay tuned for a better answer...
- albertzeyer 14y agoI'm not sure if I would agree on this. Take for example the Linux kernel. You have basically early exits just everywhere. Take any random file from here: http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=tree;f=kernel;hb=HEAD http://git.kernel.org/?p=linux/kernel/git/stable/linux-stabl... It often goes like this: check if we have already done this or so -> exit check if this is possible to do. if not -> exit do some first thing. on error -> exit do some other thing. on error -> exit ...
- henrik_w 14y agoThis coding style is also referred to as "guard clause", embraced by e.g. Martin Fowler (http://martinfowler.com/refactoring/catalog/replaceNestedConditionalWithGuardClauses.html http://martinfowler.com/refactoring/catalog/replaceNestedCon...) and Jeff Atwood (http://www.codinghorror.com/blog/2006/01/flattening-arrow-code.html http://www.codinghorror.com/blog/2006/01/flattening-arrow-co...) (and by me ;-))
- deleted 14y ago[deleted]
- daengh 14y agoHe also said his statement "This is never about what runs fastest...". Kernel code needs to run fast and take advantage of shortcuts. IME, the jobs most programmers are doing don't need to try to accomplish maximum speed or need to wring a few bytes out of RAM. Certainly we don't want to be wasteful, but long-term maintainability is more important, again IME, than absolute speed or minimising memory footprint by a few (k) bytes. Back in the bad old days when I was writing programs to run on mainframes, yeah, we did need to fight for every byte. A $5 million machine back then had less RAM and less raw CPU power than a tablet does today. We don't live in that world now.
- masklinn 14y ago> He also said his statement "This is never about what runs fastest...". This style has nothing to do with running fast, it has to do with lowering the cognitive load of the rest of the function. A branch means you have two states to keep in mind (the state where the branch is taken, and the state where the branch is not taken). Without early exit, you have to keep both states in mind until the end of the function just in case. With guard clauses, you can discard on of the states (the one which matched the clause) entirely.
- pooriaazimi 14y agoI think the biggest problem is that early exits make you forget you have to clean things up before returning (a bigger problem in C and sometimes Java, than it is in modern dynamic languages). There are certainly other reasons, but I'll leave them to others that are more experienced!
- pooriaazimi 14y agoAs always, google is our friend. Some links: http://www.osdata.com/programming/loops/earlyexit.html http://www.osdata.com/programming/loops/earlyexit.html http://programmers.stackexchange.com/questions/118703/where-did-the-notion-of-one-return-only-come-from http://programmers.stackexchange.com/questions/118703/where-...
- eranation 14y agoThis was a good resource: http://en.wikipedia.org/wiki/Control_flow#Early_exit_from_loops http://en.wikipedia.org/wiki/Control_flow#Early_exit_from_lo...
- njharman 14y agoIndeed. I have found "guard clauses" with return/error at top of function to be clearer and less error prone.