Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

411–420 of 601 posts

Re: Avoid Else, Return Early (2013)

#411

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 actually gone from avoiding else to requiring else, which is sort of a necessity when you're in a functional immutable environment where the result of a logical expression is a value (and often assigned as such), since it avoids undefined situations.

(This example comes from Elixir.)

value = if boolean, do: this_value, else: other_value

is undefined in some circumstances unless an "else" is included.

This pattern might seem weird to OOP folks (the assignment, not the ternary-operator-style logic), but in Elixir-land, it is not only considered superior to assigning inside if/then logic, you actually get a compiler warning if you assign/bind to a variable inside a logical expression because (again) that value becomes undefined as soon as you leave local scope (or re-acquires the value it had in the outer scope, thanks to immutability).

And if you think about it, values can only travel in one direction using this scheme, which further simplifies reasoning about information flows.

I would argue that this is also superior to early-exit as having one entry point and one exit point is much easier to reason about, and because the extra logical complexity you're ostensibly trying to avoid writing by early-exiting is actually still there, it's just obfuscated... and that complexity should be made obvious (in which case, if it's extensive, it would be a code smell... consider the example of a function with 25 early exits that "looks flat" visually, but which actually has 25 different branches)

Re: Avoid Else, Return Early (2013)

#412

Earlier quoted context omitted.

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

Can't that be taught as well? (both rules, and exceptions to rules?)

Sure.

But as a novice youd should adhere to rules. As you gain experience you learn when to break them.

Re: Avoid Else, Return Early (2013)

#413
post #107

I always found this type of "general purpose" coding rules rather useless and often counter-productive because some coders (especially beginners) will often cargo-cult and apply them without rhyme or reason. I've known coders who had the opposite rule: never have more than one return per function, use if/elses for the control flow (TFA mentions that). I don't know where this rule came from and neither did they, it's…

That's why newer languages have try-finally.

Basically

Allocate resource

try

guard clause (early return)

logic

finally

deallocate

Basically, the try-finally clause guarantees that the finally clause is run when there is an early return.

Re: Avoid Else, Return Early (2013)

#414

Earlier quoted context omitted.

Ceteris paribus, shorter code always is more readable. It's the only guideline I've found true regardless of programming language or environment. Shorter is better.

It depends. Short, dense code can make the code more difficult to understand/change later, while overly bloated code can have the same effect. I often find inelegant, yet straightforward solutions are generally better options than dense, mathematically pure solutions, simply because inelegant code usually relies on fewer assumptions. Noting that code rarely/never evolves the way we expect it to, apply Occam's razor a…

No it doesn't depends. That's what ceteris paribus means.

Re: Avoid Else, Return Early (2013)

#415

Earlier quoted context omitted.

Pragmatic programming has lost. If you aren't a zealot about being pedantic, just move into the old-folks home.

I'd say it's the opposite. Code formatters are winning. It's becoming increasingly trite to bikeshed over formatting when projects are using code formatters.

As Andy Lester recently tweeted (but said it wan't his): Should "bikeshedding" be hyphenated?

I should see if he remembers where he got it.

Re: Avoid Else, Return Early (2013)

#416

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 find myself doing the same for many of these points. I wonder what the point is then to hit OOP so hard in CS majors if at the end of the day production code isn't written like that. I guess my question is more the validity of seemingly esoteric concepts when practical programming evolves to the list in the post by drawkbox.

Re: Avoid Else, Return Early (2013)

#417
post #345
post #279

Earlier quoted context omitted.

The irony is that Python actually has open-braces, but they're spelled ":" instead of "{". And the syntax effectively enforces K&R style. When I write Python I end every block with a "pass" statement so that emacs can auto-indent my code properly. The "pass" statement thus effectively becomes a close-brace. It drives Pythonistas into conniptions, but I never have to worry about reverse-engineering a block of code to…

That's the bad part of not having braces. If boundaries exist they need to be clear. One shouldn't have to count the tabs that make up the level of indentation. Its already a challenge reading code. Counting invisible tabs makes it even worse.

On the other hand high counts of invisible tabs may be a hint that the code needs refactoring..

Re: Avoid Else, Return Early (2013)

#418
post #309
post #293

Earlier quoted context omitted.

The start of the code block is signified by the opening brace, which starts at the end of the method name in the first case, hence breaking symmetry.

To my eye, the start of the code block is signified by the indentation, i.e.: stuffstuffstuff.... stuffstuffstuff... So I read C and Python (and Lisp) code the same way. A naked open brace looks jarring and ugly to me. It also increases the separation of other related parts of the code, i.e. if (...) { while(...) { do(...) { vs if (...) { while(...) { { do(...) { The latter seems unnecessarily wasteful to me.

K&R isn't that terrible when code is neat and clean, but it starts to have trouble IMO particularly when declarations or conditions wrap to multiple lines. Compare the following examples... I personally have to stop and read the code to find the blocks with K&R braces, vs being able to see them at a glance with Allman.

    void MyLongMethodName(SomeLongParamType param1, SomeOtherLongParamType param2,
        YetAnotherLongParamType param3) {
        if (longContrivedVariableName1 == longContrivedVariableName2 && 
            longContrivedVariableName1 != longContrivedVariableName3) {
            // do stuff
        }
    }
    
    void MyLongMethodName(SomeLongParamType param1, SomeOtherLongParamType param2,
        YetAnotherLongParamType param3) 
    {
        if (longContrivedVariableName1 == longContrivedVariableName2 && 
            longContrivedVariableName1 != longContrivedVariableName3) 
        {
            // do stuff
        }
    }

Re: Avoid Else, Return Early (2013)

#419

Earlier quoted context omitted.

Oh common. This might be true for a very specific type of codebase, but it isn't true for programming in general. If I'm coding a library of standard statistical functions I'm exiting early. If I'm coding a Rails webapp I'm exiting early. If I'm coding a shell script, even one used on tens of thousands of servers, I'm exiting early. The resource almost all programmers are managing is the resource of human time. Human…

Don't forget the human time to debug the code (especially the rare or only-happens-under-load issues, which can be related to resource exhaustion, among other things). Also, some of your examples (like altering or reviewing code) can become easier and faster if resource management is a first-class citizen in your code base or language (i.e. is either more explicit in the code, and you know to look for it and manage i…

Yeah that is true.

Re: Avoid Else, Return Early (2013)

#420

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 actually gone from avoiding else to requiring else, which is sort of a necessity when you're in a functional immutable environment where the result of a logical expression is a value (and often assigned as such), since it avoids undefined situations. (This example comes from Elixir.) value = if boolean, do: this_value, else: other_value is undefined in some circumstances unless an "else" is included. This patter…

That's just a ternary operator. I use that in Java all the time.

    value = boolean ? this_value : other_value;
If the branching logic gets too complicated, I usually move it into a function (private method) with a return in each branch.
Post reply on HN