Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

31–40 of 601 posts

Re: Avoid Else, Return Early (2013)

#31
Before I heard about the single exit point rule, I have coded during many years using multiple exit points. I am complying with the rule for many years and I am quite happy with it. The code is slightly more nested, very slightly longer to type. But OTOH, the style checker can spot mistakes in my code and there is less thinking about how I will structure my code to make it smarter.

IMHO, the gain is small but not smaller than the cost.

Re: Avoid Else, Return Early (2013)

#32
post #7

Avoid rules, use your judgment.

Judgment is subjective so this pattern fails when there are more than one person reading the code or the same person at different time.

You end up with code written in several different styles within the same codebase. Assumptions that don't hold, etc. Much harder to reason about and maintain.

Re: Avoid Else, Return Early (2013)

#33
post #9

Seems to me that there is quite a bit of commentary on this subject, and you can find it by searching for its typical solution: guard clauses[1]. [1] http://wiki.c2.com/?GuardClause

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}) ->
        % handle results
        .

Re: Avoid Else, Return Early (2013)

#34
post #8
post #3

"removing a whole line and more braces" - this is really fighting the wrong enemy. Code should be written in a way it is more readable, not shorter.

Exactly. This led to the famous OSX double goto bug [0] if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; ... other checks ... fail: ... buffer frees (cleanups) ... return err; [0] https://www.dwheeler.com/essays/apple-goto-fail.html

The "Avoid Else, Return Early" blog post above appears to be about JavasScript code, which (along with Java, C#, Python, Ruby etc) do not ready do "buffer frees (cleanups)" much. They have other language and runtime mechanisms for this such as GC and try...finally blocks, which work fine with early return.

Yes, in the presence of teardown code at the end of the method, as is common idiom in C, avoid early return. This appears to be the case for apple's "goto fail" code.

However, don't generalise this to all languages.

Re: Avoid Else, Return Early (2013)

#35
post #20
post #8

Earlier quoted context omitted.

Exactly. This led to the famous OSX double goto bug [0] if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail; ... other checks ... fail: ... buffer frees (cleanups) ... return err; [0] https://www.dwheeler.com/essays/apple-goto-fail.html

`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.

Re: Avoid Else, Return Early (2013)

#36
post #5

I would agree. Putting "early out" logic at the beginning allows the one who reads the code to lower the cognitive load a bit. Basically "I know I can read the following code safely because the error handling and parameter sanitizing is done". But that only works with mundane operations (error handling, parameters sanitizing). If the operations convey some important semantics, then I prefer to see the guarded code in…

If something is truly exceptional, this is a particularly good use for Debug.Assert. You have it fail in debug mode to help catch edge-cases but pass but returning early production (which may be more performant or otherwise wanted instead of throwing an exception).

Re: Avoid Else, Return Early (2013)

#37
post #5

I would agree. Putting "early out" logic at the beginning allows the one who reads the code to lower the cognitive load a bit. Basically "I know I can read the following code safely because the error handling and parameter sanitizing is done". But that only works with mundane operations (error handling, parameters sanitizing). If the operations convey some important semantics, then I prefer to see the guarded code in…

Big blocks of if/else logic impose a heavy cognitive load. I find that anytime your eyes have to jump more than a few lines there's higher mental overhead

Re: Avoid Else, Return Early (2013)

#38
post #31

Before I heard about the single exit point rule, I have coded during many years using multiple exit points. I am complying with the rule for many years and I am quite happy with it. The code is slightly more nested, very slightly longer to type. But OTOH, the style checker can spot mistakes in my code and there is less thinking about how I will structure my code to make it smarter. IMHO, the gain is small but not sma…

> single exit point rule,

What makes it a "rule" or as sometimes said, a "law"?

It's just a style, and it has pros and cons, cases where it helps, and cases where it hinders.

Re: Avoid Else, Return Early (2013)

#40
post #7

Avoid rules, use your judgment.

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 guys in different teams, etc. The one rule was "write like a chameleon, and make your code look like the code it is in." (okay... to make that work, the other was "spaces, not tabs")

The code was generally very readable, and it was a very adult codebase. The problem with hard rules is that comprehensive codification of complete rulesets is fundamentally intractable. You're always going to run into areas that don't fit, or the ruleset will be laughably overwrought (and, thus, impossible to put into practice).

You could call it the code-zealot incompleteness theorem...

Of course, if I get to make all the rules and have no obligation to be complete, consistent, or considerate, I can get on board with this plan.

Post reply on HN