Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

71–80 of 601 posts

Re: Avoid Else, Return Early (2013)

#71

A longer essay on similar issues: http://www.anthonysteele.co.uk/TheSingleReturnLaw

Oh gosh yes. If I had a dollar for every time someone forgot a break statement in a "Found item in loop" scenario...

Well, LINQ ended that issue for me ;)

Re: Avoid Else, Return Early (2013)

#72

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 while/do/while is usually fades away, and if needed exit conditions.

I couldn't interpret this sentence.

Re: Avoid Else, Return Early (2013)

#73

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 var…

> I was made to have only one exit point for some projects Did they give any rationale for this?

It should be easier to reason about code when there is exactly one exit from a block. I am not sure this really applies when we are talking about guard clauses that are not deeply nested. So loop breaks and other shallow returns are OK, and can be good.

Re: Avoid Else, Return Early (2013)

#74
post #57

I have read somewhere else ( https://softwareengineering.stackexchange.com/questions/1187... ) that the "single exit" rule was not actually about having only one place where the function returns, but actually about having a single place where the function returns to . That rule seems to have been so successful, that no modern language I know of allows (the original definition of) multiple entry or multiple return (ex…

Forth may not qualify as "modern" for some (though it still has a way of staying around in some contexts, like bootloaders), but it does allow code to store to and retrieve from the return stack, which is also used for loops.

If you read that and thought "does that mean I can change loop iteration order and returns programmatically?!?" and/or "WTF?!", the answer is, yes, to all of it. WTF indeed.

I've never actually seen a non-pathological use for this language feature.

Re: Avoid Else, Return Early (2013)

#75
post #72

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 while/do/while is usually fades away, and if needed exit conditions. I couldn't interpret this sentence.

Edited, basically do not use while loops, if you do tread carefully and provide yourself an exit. You don't want to be the one that nukes the server.

Re: Avoid Else, Return Early (2013)

#76
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…

The pre-conditions are called Guard Clauses [0]. It's really useful to think about guard clauses and explicitly look for them to ensure the pre-conditions are met rather than have them appear over time as if/else blocks.

edit: now that I've looked through the comments I see these are mentioned on numerous other threads.

[0]: https://en.wikipedia.org/wiki/Guard_%28computer_science%29

Re: Avoid Else, Return Early (2013)

#77

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)

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

JavaScript has the guard operator. It can really clean up your control flow when you know it's a guard operator and not just logical AND.

A big gotcha with `&&` as a guard in JS is that it can return any falsey typed value if you don't coerce the guard to a boolean.

e.g.

    const check(cond) => cond && otherValue
If `cond` is falsey, it returns `cond`.

This means the function could return any of: `false`, `undefined`, `null`, '', `0` or `NaN`.

This is a fairly common issue I see with React + JSX:

    {cond && }
If `cond` is `false`, `null`, `undefined` or '', everything will be just fine, but if `cond` happens to be a zero or `NaN`, suddenly you have a weird `0` or `NaN` rendering in your page. Oops.

Low cost, much safer guard:

    const check(cond) => !!cond && otherValue

Re: Avoid Else, Return Early (2013)

#79
post #58

Earlier quoted context omitted.

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.

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 up just being easier to deal with. This is especially true in languages like Rust, where if/else is an expression, leading to the following construct being used often (although usually with more complicated content):

    let max = if (x > y) {
        x
    } else {
        y
    };
Note that "max" is immutable despite the conditional assignment due to the if being used as an expression.

Re: Avoid Else, Return Early (2013)

#80

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]
Post reply on HN