Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

101–110 of 601 posts

Re: Avoid Else, Return Early (2013)

#101
post #40

Earlier quoted context omitted.

That's awful advice. Obviously _someone_ has to use their judgement to _create_ the rules. But if you have a large codebase that lots of people are interacting with, letting everyone "use their judgement" is going to create an unreadable mess of code, because you're going to have different patterns and approaches all over the place. It would be like writing a book and one paragraph is in English, the next in Spanish,…

I worked in a shop that lived by "use your judgement", and it was really the cleanest body of code that I've ever worked in with more than 30 people, in 20 years of professional coding. Why? Because people with bad judgement were mercilessly brow-beaten into developing better judgement. We had lots of different styles of code hanging around, and you could tell if code had been written by our CTO, our leads, different…

> The one rule was "write like a chameleon, and make your code look like the code it is in."

I bounce between many code bases in multiple languages, and this has always been my rule. I first figure out why/how are things done, and then do them the same way within reason. If the existing code has something done in a way that is no longer valid/correct, then we have discussion about changing all of the code.

Re: Avoid Else, Return Early (2013)

#102
post #58

Earlier quoted context omitted.

I am arguing this is worse, since it expresses the logic in a more convoluted way.

I would argue that it is by no means more convoluted. It is quite clear and concise. All of the following are equally readable: if (x > y) { return x; } else { return y; } if (x > y) { return x; } return y; return (x > y) ? x : y; The logic would be convoluted if you are going through extra hoops in order to write your logic like this, making the flow of the application unclear. For some things, an else branch ends u…

I think it's only clear and concise looking because of the achilles heel of this entire thread: terse examples. As soon as you need to do more than a single line of work, the else'd version becomes far more readable (due to superior indentation and clearer guarantees of what happens when).

If it's a single line of return in both branches, then a ternary expression is usually going to be ideal instead.

Re: Avoid Else, Return Early (2013)

#103
I've been slowly trying to get back into hobby/side development after not being a professional developer for 11 years. Even when I was a full-time developer, I was never really in a "junior" role or dropped into an existing, quality codebase, so much of what I was doing was from scratch. Although my coding did improve as our team grew and it forced me to be more disciplined, I never learned a lot of little hints like this that make your code much clearer.

In getting back into it, I've relied a lot of Laracast's tutorials in both learning Laravel, along with how much PHP has evolved in the past 11 years, but also some of his code quality videos, which included one on this very topic! After seeing that, I immediately started refactoring some recent code I had written with the goal of flattening it to as few indents as possible by eliminating else's and elseif's. Sure enough, I was much happier with the refactored code than I was with the original, even if the output of the code was the same.

Re: Avoid Else, Return Early (2013)

#104

Programmers with lots of hours of maintaining code eventually evolve to return early, sorting exit conditions at top and meat of the methods at the bottom. Same way you evolve out of one liners. Same way comments are extra weight that should only be in public or algorithm/need to know areas. Same way braces go on the end of the method/class name to reduce LOC. Same way you move on from heavy OO to dicts/lists. Same w…

Same as we now use TL;DR

Exit or get out quick... make it readable... then the meat is left for those that want it below...

Re: Avoid Else, Return Early (2013)

#105
post #6

A more formal name for this approach is / could be Guard Clauses: https://refactoring.com/catalog/replaceNestedConditionalWith... . This pattern has been elevated to a language construct in Swift: https://thatthinginswift.com/guard-statement-swift/

Agreed, when I was first exposed to Guard clauses, (albeit in Elixir), I was amazed at how intuitive it felt to use them.

https://hexdocs.pm/elixir/master/guards.html

Re: Avoid Else, Return Early (2013)

#106

Programmers with lots of hours of maintaining code eventually evolve to return early, sorting exit conditions at top and meat of the methods at the bottom. Same way you evolve out of one liners. Same way comments are extra weight that should only be in public or algorithm/need to know areas. Same way braces go on the end of the method/class name to reduce LOC. Same way you move on from heavy OO to dicts/lists. Same w…

> Same way braces go on the end of the method/class name to reduce LOC.

Screw that. I've been writing code for 15 years, and Allman style braces make it so much easier to mentally parse code into blocks that they're worth every single LOC. I can't speak for anyone else but I'm not working on an 80x24 terminal anymore.

Re: Avoid Else, Return Early (2013)

#107
I always found this type of "general purpose" coding rules rather useless and often counter-productive because some coders (especially beginners) will often cargo-cult and apply them without rhyme or reason. I've known coders who had the opposite rule: never have more than one return per function, use if/elses for the control flow (TFA mentions that). I don't know where this rule came from and neither did they, it's just how they were taught I suppose. Replacing that with yet an other "rule of thumb" is a bad idea IMO.

Writing clean and maintainable code is as art and requires balancing many variables. Sometimes an early return is warranted, sometimes an if/else might make more sense. If you're writing C code and you need to release some resource before returning (mutex, file handle etc...) then an early return might be error-prone and an "else" or "goto" might result in cleaner and more readable code. I use gotos a lot in error handling in C, I think it's a superior pattern to the one proposed by TFA if you have a lot of cleanup to do. In C++ and other object-oriented languages it's less of an issue thanks to RAII and/or GC.

Beyond that if/else might be more readable if both clauses are on the same "level" semantically. For instance if you write:

    if (some_cond) {
        do_a();
        return;
    }

    do_b();
It looks like `do_a` and `do_b` are not on the same "level", semantically speaking. If instead they're two variations of the same concept then an else might make more sense.

Re: Avoid Else, Return Early (2013)

#108

Programmers with lots of hours of maintaining code eventually evolve to return early, sorting exit conditions at top and meat of the methods at the bottom. Same way you evolve out of one liners. Same way comments are extra weight that should only be in public or algorithm/need to know areas. Same way braces go on the end of the method/class name to reduce LOC. Same way you move on from heavy OO to dicts/lists. Same w…

> Same way comments are extra weight that should only be in public or algorithm/need to know areas.

Unless you are writing completely brilliant code your future self will hate you if you skimp on comments. Also self-documenting code is great, but intentions are not always clear to another person trying to figure out your code.

Re: Avoid Else, Return Early (2013)

#109
The one liner is the wrong conclusion.

Why?

1) When using a debugger, it takes more effort to place a breakpoint on the inner statement.

2) If you want to insert statements inside the if block you will be changing version control history for statements other than what you are modifying.

About 2, you may argue that this will be the case anyways because braces are not used... the solution to that is to always use braces.

Then there's another important aspect: handling error conditions is important part of your logic. Do not sweep them under the rug. Proper error handling is a big part of what makes applications robust, they need to be as readable as everything else.

Re: Avoid Else, Return Early (2013)

#110

Sort of agree, but I don't think if (err) { handleError(err) return } and if (err) return handleError(err) are equally good. The second one doesn't really make it clear wether handleError returns a value and that value is intended to be returned.

If the return value is important:

    if (err) return void handleError(err)

And in non-promise-based async JS, the return value is almost always lost/useless anyway so `return x` has no effect, might as well repurpose `return` for short-circuiting.
Post reply on HN