Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

191–200 of 601 posts

Re: Avoid Else, Return Early (2013)

#191
post #87
post #63

This also works well with a C++ `defer` helper. #define CONCAT_LITERAL(x, y) x ## y #define CONCAT(x, y) CONCAT_LITERAL(x, y) template struct DeferWrapper { F f; DeferWrapper(F f) : f(f) {} ~DeferWrapper() { f(); } }; template DeferWrapper deferWrapper(F f) { return DeferWrapper (f); } #define defer(code) auto CONCAT(_defer_, __COUNTER__) = deferWrapper([&]() code) Example of usage: { Foo *foo; if (initializeFoo()) {…

You're turning RAII upside down... Learn to use proper RAII and you won't need this defer hack.

Tell that to the APIs I work with, like POSIX sockets/Winsock, etc. You're suggesting that I wrap them all with RAII? That's ridiculous when you have hundreds of C types which are all used just once or twice. Using defer makes elegant/simple C-like code because it uses the C APIs directly and is nearly the same number of lines of code as a C programmer would write without using defer.

I fail to see how "learning proper RAII":

    struct FooWrapper {
        Foo *foo;
        FooWrapper(...) {
            foo = initializeFoo(...);
            if (!foo)
                throw FooException(...);
        }
        ~FooWrapper() {
            destroyFoo(foo);
        }
    }

    try {
        FooWrapper fooWrapper(...);
    }
    catch (FooException &e) {
        ...
    }

is easier than

    Foo *foo;
    if (initializeFoo(foo, ...)) {
        ...
    }
    defer({
        destroyFoo(foo);
    })

If this isn't what you meant, could you demonstrate?

Re: Avoid Else, Return Early (2013)

#192
post #174

There are major issues with not using else - in that there is no obvious way to test whether it should be there or not. Any programmer returning to your code (or even you returning to your code a year later) can't know what the intention was/should be, and neither can the compiler. I try (in C#) to avoid if/else completely (not always possible, but it's a general guide) and I try to work with ternary expressions inst…

You aren’t really reducing complexity with the monadic approach, just replacing explicit control flow for implicit control flow masked as data flow. Debugging can become harder in the latter case.

Which is written once, rather than 1000s of times. That's a reduction in cognitive load and the same 'missing else' bugs I mentioned.

I agree it's not always easier to debug - but mostly (I find) writing code as pure expressions rather than a sequence of statements reduces the need for debugging massively. So, I don't think it's quite as black and white as you paint.

Re: Avoid Else, Return Early (2013)

#193

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…

[deleted]

Re: Avoid Else, Return Early (2013)

#195

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…

I've been coding about 20 years now, and I've seen all of these changes in my own coding style.

Re: Avoid Else, Return Early (2013)

#196
post #142

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…

This is like the 10 commandments. Good ideas mixed with stuff that is a matter of taste :) If it was this simple we wouldn't be still arguing about coding styles decades after they were invented. I know few old programmers that I respect very much, and they don't agree about the perfect coding style, not even simple stuff, like braces in separate lines or not.

If it was this simple we wouldn't be still arguing about coding styles decades after they were invented.

Money quote.

Re: Avoid Else, Return Early (2013)

#197

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…

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.

Re: Avoid Else, Return Early (2013)

#198
post #119

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.

Only "brilliant" code ends up needing comments. Plain code organized into understandable methods (usually no more than half a page of code), with good naming for variables & method names reduces the need for comments. It's also easier to scan/read code if there's a minimum of comments in the way.

Sometimes requirements or quircks of third party library need a comment.

Re: Avoid Else, Return Early (2013)

#199
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 learned some Swift when it as at 1.2 and I'm happy to see it evolve so quickly and take common statements, like the optional unwrapping "very long `if let` statement" mentioned article, and simplify it. I really should get back into Swift.

Swift also has the `defer` statement which makes this particular approach usable even if there is cleanup to do before the function can exit.

Re: Avoid Else, Return Early (2013)

#200

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…

> Programmers with lots of hours of maintaining code eventually evolve to return early, [..]

I agree with all your other points and I‘d even agree if you wrote return early makes code more readable but not that it‘s something experienced programmers do.

Programming is still - to some degree - resource management. Inexperienced devs often miss that fact, because they are focused on memory management and believe they can rely on the garbage collector for clean-up. In real projects you quickly end up managing file descriptors, sockets, handles, GUI resources, etc. Early return is terrible for that, because your coding style starts to depend on the kind of resource to manage.

That‘s why the more experienced folks end up writing single exit point code sooner or later.

EDIT: I‘m not arguing that early return and proper resource management are incompatible, just that most experienced programmers have often been burnt enought to avoid it.

Post reply on HN