Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

41–50 of 601 posts

Re: Avoid Else, Return Early (2013)

#41
It depends! But it depends on the actual meaning of the code, so examples which use meaningless identifiers like `doStuff()` miss the distinction.

If the conditions are semantically symmetrical, if/else is the right approach:

     fun max(a, b) {
        if a > b { a } else { b }  
     } 
But is it a precondition which causes you to skip the primary logic of the function, then get it out of the way early:

     fun max(a, b) {
        // special case for null
        if a==null or b==null { null }
        
        if a > b { a } else { b }  
     }
Yeah we want to reduce indentation, but not at the cost of making the code overall harder to follow. The logic of "max" is much clearly expressed as a single expression with `else`.

Re: Avoid Else, Return Early (2013)

#43
post #20

Earlier quoted context omitted.

`goto` wouldn't be used in a return early philosophy.

Goto is heavily used to return early, by jumping to the cleanup section at the bottom of the function. Otherwise, you have to repeat the cleanup code at each exit point, or use the dreaded pyramid of doom where each failure point introduces another indent level, which is what the author here is trying to avoid in the first place.

"cleanup section at the bottom of the function" is pretty rare in JavaScript, which is what the original blog post is discussing. Same with Java, C#, Ruby etc.

No, it doesn't play well with early return, so avoid mixing them.

Re: Avoid Else, Return Early (2013)

#45

This refactoring is so simple and obvious I don't even understand why some people don't write like this by default. I've had colleagues comment my PR on my "failed validation, return early" code saying "we generally strive to maintain one single point of return". I mean, why would you want only one return even?

> I mean, why would you want only one return even?

Some other comments here discuss resource cleanup issues that can creep into C code with early return.

If you're not coding in C, then more likely it's pure cargo-cult.

Re: Avoid Else, Return Early (2013)

#46
I was made to have only one exit point for some projects and it drove me up the wall. It only really makes sense if you're coding in languages like C. I don't like functions written this way because they're longer, are harder to read, have complex nesting and most of all they introduce state (the variable that stores the result). In dynamic languages, you're not going to get warned if you forget to set the result variable and if you forget the variable can be returned as a null which is a horrible source of bugs.

Re: Avoid Else, Return Early (2013)

#47
post #41

It depends! But it depends on the actual meaning of the code, so examples which use meaningless identifiers like `doStuff()` miss the distinction. If the conditions are semantically symmetrical, if/else is the right approach: fun max(a, b) { if a > b { a } else { b } } But is it a precondition which causes you to skip the primary logic of the function, then get it out of the way early: fun max(a, b) { // special case…

Exactly this. Anyone who put their shoe in functional programming can make such a distinction.

Early returns are not a panacea. If/Else-everything is not a silver bullet either.

Re: Avoid Else, Return Early (2013)

#48
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/

I was more or less required to use guard clauses by my manager at my previous job.

I used to hate being forced to use them, just because as a recent computer science graduate I was happy with nested conditionals everywhere. But guard clauses make life so much easier, I eventually discovered.

They make testing your code a lot easier, and also make reasoning about the code and reading it so much easier.

Ruby makes writing methods with guard clauses a breeze, since you can just write something like `return if x > 7`.

Re: Avoid Else, Return Early (2013)

#49
post #9

Earlier quoted context omitted.

Yeah, Swift in particular really embraces that pattern.

Also functional languages with function guards e.g. while Erlang/Elixir does not have a return statement (and thus early return) you can write handle(Err, Results) when Err /= undefined -> handle_error(Err); handle(_, Results) -> % etc… . though errors would generally be reified as the ad-hoc union of two tuples and would look more like this: handle({error, Info}) -> handle_error(Info); handle({ok, Results}) -> % han…

The functional style that you show certainly has multiple points where a value is returned, so you could call it "early return"; even if as a syntactic shorthand the keyword "return" is omitted. This is common across a lot of functional languages.

Re: Avoid Else, Return Early (2013)

#50
post #41

It depends! But it depends on the actual meaning of the code, so examples which use meaningless identifiers like `doStuff()` miss the distinction. If the conditions are semantically symmetrical, if/else is the right approach: fun max(a, b) { if a > b { a } else { b } } But is it a precondition which causes you to skip the primary logic of the function, then get it out of the way early: fun max(a, b) { // special case…

You could still write it as

    fun max(a, b) {
        if a > b {
            return a
        }
        return b
    }
Not saying this is necessarily better or worse. The point I want to make is that your case isn’t special.
Post reply on HN