Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

361–370 of 601 posts

Re: Avoid Else, Return Early (2013)

#361
post #197

Earlier quoted context omitted.

For whatever it's worth, I insisted on single return for a long time when I was an intermediate programmer. 30 years in, I strongly prefer return early (as well as continue early in loops) and I cannot go back. The immensely reduced indentation is marvelous. Having that 'happy path' consolidated is more readable.

I am on board with returning at the beginning while checking arguments. But I hate it when code returns somewhere in the middle for some reason. I have spent countless hours debugging a problem with unexpected behavior only to find a return statement in the middle of a huge block to code.

That's because the return statement is a kind of goto statement. Goto-like statements reduce the value of structured programming. In a pure structured program, each statement sequence is either completely executed or not executed. There are also pure structured languages, like Oberon, which doesn't allow impurely structured programs.

Re: Avoid Else, Return Early (2013)

#362

Earlier quoted context omitted.

"this... to reduce LOC ? Doesn't feel like a valid reason in any language using braces..." It's not really a valid reason. Unfortunately, there are still a lot of people who think LOC is a valid metric.

Here's an extreme, yet very real example: mandatory Doxygen comments on accessors: /** * Get the foo * * @return the foo */ int getFoo(); /** * Get the bar * * @return the bar */ float getBar(); /** * Set the foo * * @param foo the foo */ void setFoo(int foo); /** * Set the bar * * @param bar the bar */ void setBar(float bar); Compare with what any sane project would do: int getFoo(); float getBar(); void setFoo(int…

Meh. It's noise but what's the harm? It was generated by an IDE so nobody had to physically type that. And usually no developer will be dwelling on this object or this area of the object. It just sits there doing no harm to anyone.

>LOC is more valid as a metric than most care to admit.

It's not.

Re: Avoid Else, Return Early (2013)

#364

Earlier quoted context omitted.

I'm with you on Allman style braces, prefer it and find them much easier to read. As everyone else seems to use K&R I've just had a adapt over time :-(

A pro maintains consistency though so that is good. I like One True Brace Style (1TBS) with an uncuddled 'else', which has else/else if on new-line with the break before it (similar to Stroustrup K&R without any same line properties, one thing per line, no bracket-less statements) and setup the standard that way if I am designing it, but do Allman or whatever variant the codebase uses if it already exists.

I’m with you on this, and all that other stuff you said. But really, on the topic of braces, brackets and parentheses, any decent editor will highlight the matching brace for you.

Re: Avoid Else, Return Early (2013)

#365
post #325

Certainly is hard to read nested code, but returning earlier makes it harder because now our mind has to construct the execution path instead of reading it. What I usually do is writing the body in a new procedure. Dijkstra designed a language with no return statement with a very simple semantics made for proving the program behaves exactly as its specification mandates. Niklaus Wirth designed Oberon with no return s…

Golang is not comparable, as you get to leave failures not handled explicitly because its goto-fail scheme. I mean, that's a very nice feature of Go, but not comparable.

The danger with early returns is failure to handle all cleanup. This is really a failure of many programming languages. Golang gets this right. But even so, I'd rather have early returns (or early goto-fails) than ever deeper if/else ladders.

Another option that works very well is this:

    ret = thing1(...);
    if (ret == 0)
        ret = thing2(...);
    if (ret == 0)
        ret = thing3(...);
    if (ret)
        ;
    return ret;

Re: Avoid Else, Return Early (2013)

#366

Earlier quoted context omitted.

"this... to reduce LOC ? Doesn't feel like a valid reason in any language using braces..." It's not really a valid reason. Unfortunately, there are still a lot of people who think LOC is a valid metric.

Here's an extreme, yet very real example: mandatory Doxygen comments on accessors: /** * Get the foo * * @return the foo */ int getFoo(); /** * Get the bar * * @return the bar */ float getBar(); /** * Set the foo * * @param foo the foo */ void setFoo(int foo); /** * Set the bar * * @param bar the bar */ void setBar(float bar); Compare with what any sane project would do: int getFoo(); float getBar(); void setFoo(int…

Also: Why use get and set accessors for private fields at all, when you can just use:

int foo; float bar;

That can later be changed, when the need arises.

Re: Avoid Else, Return Early (2013)

#367
Another option that works very well is this:

        ret = thing1(...);
        if (ret == 0)
            ret = thing2(...);
        if (ret == 0)
            ret = thing3(...);
        if (ret)
            ;
        ;
        return ret;
No ever-deepening if/else ladders, and no goto-fails.

Alternatively:

        if ((ret = thing1(...))
            goto out;
        if ((ret = thing2(...))
            goto out;
        if ((ret = thing3(...))
            goto out;
    out:
        if (ret)
            ;
        ;
        return ret;
This has a goto-fail, but only one, so it's Go-like.

Re: Avoid Else, Return Early (2013)

#369
post #197

Earlier quoted context omitted.

For whatever it's worth, I insisted on single return for a long time when I was an intermediate programmer. 30 years in, I strongly prefer return early (as well as continue early in loops) and I cannot go back. The immensely reduced indentation is marvelous. Having that 'happy path' consolidated is more readable.

I find it interesting how most of the comments about return early are based on experience. I had the same thing happen about 10 years in. I just got sick of the extra coding and long indented blocks. And just switched over one day. Why is this not taught from day one?

The problem is that for any rule you come up with there are cases where that rule is just too rigid and too inflexible.

There are times where early return makes a ton of sense. Usually that's the case when you can derive the return value from a shallow interpretation of some input values (i.e. check preconditions) but still require more complex processing for other input values. In that case, return early, but constrain the rest of the method to one return point.

On the flip-side, there are cases where an early return makes it incredibly hard to reason about the function. This usually occurs in dense, nested conditional logic. In those cases, I found sticking to rule that a return value should be initialized once and only once, and return from a single point, beneficial in even reasoning about the problem.

Re: Avoid Else, Return Early (2013)

#370
post #155

Earlier quoted context omitted.

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

> your future self will hate you if you skimp on comments. Likewise, your future self will hate you when comments fall out of sync with the code. If the code is readable you don't need much in the way of comments.

Code explains what the program does. Comments explain why a program does what it does. Code and comments are orthogonal, not coincident.
Post reply on HN