Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

121–130 of 601 posts

Re: Avoid Else, Return Early (2013)

#121

In Ruby these are idiomatic enough to have a name and are built into the linter, so it'll yell at you if it sees that you're not using guard clauses. As a further refinement, I will often take tricky conditional logic and put them into a method that consists of nothing but guard clauses and a return true or false at the bottom of the method. In Ruby you can use ? and ! at the end of method names, so I'll give the met…

I would love Ruby-style guard clauses in JavaScript. Sometimes I wish I’d never written anything in Ruby just so I’d stop thinking about how great it would be if other languages shared some of its features.

Re: Avoid Else, Return Early (2013)

#122

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

IME it's the "completely brilliant" code that your future self will hate you for, and needs the most comments.

Moreover, when the weight of those comments trends towards 50% being justifications for why you did it that way, it's an excellent sign that your code has gone from "brilliant" to "super-genius", as in "Wile E. Coyote, Super-Genius".

"Completely dumb" code can be read by your future self without comments. Even, sometimes, by other people!

Re: Avoid Else, Return Early (2013)

#123
The whole "return in one place and it must be the last line" thing in our coding standards here is just semantic noise - because you still have to set the "gotta return" flag and repeatedly bypass the subsequent attempts to do stuff. So it still returns up front, even if it doesn't "return" up front. It just has to spend the remaining lines of the method tiptoeing around the fact.

Re: Avoid Else, Return Early (2013)

#124
post #58

Earlier quoted context omitted.

I am arguing this is worse, since it expresses the logic in a more convoluted way.

I guess I would politely argue that creating new functions would make reading code harder in basic example such are this. You'll be jumping all round or possibly separate files. Obviously larger logic tress should be pruned. Side note: a lambda function may get around this specific instance.

The simple cases do come up though. I've written plenty of functions which amount to little more than a single if-statement and I have had people ask me to make changes like

  foo(things) {
      stuff = do_work(things);

      if (stuff) {
          return a;
      } else {
          return b;
      }
  }
into

  foo(things) {
      stuff = do_work(things);

      if (stuff) {
          return a;
      }

      return b;
   }
in code reviews.

Re: Avoid Else, Return Early (2013)

#125

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.

Comments are not documentation. Documentation explains HOW to use a thing. Good comments explain WHY a thing is strange. Bad comments explain WHAT a thing does and must be made redundant by extracting and naming the thing.

> Comments are not documentation.

Probably overly generalized to be pithy, but no.

Comments are by very definition documentation, which can and should cover of all of the what/why/who/how/where.

Documentation that occasionally explains how to use code can actually be useful!

Unless you actually get around to writing a user manual (which gets out of date), please do consider documenting how something should be used, particularly in libraries.

Re: Avoid Else, Return Early (2013)

#126

If you have a complicated function, and several exit points where you want to bail out, they why not just put a "label: bail" and goto it? GOTO has a bad rap IMO. There's a place for it, and the author should probably be using it.

You're a brave person to say this in public. :D

Re: Avoid Else, Return Early (2013)

#127
post #118

Earlier quoted context omitted.

>braces go on the end of the method/class name to reduce LOC You could argue the placement of braces with lots of valid arguments both way, but this... to reduce LOC ? Doesn't feel like a valid reason in any language using braces...

Eh, all things equal, the less the number of lines the more readable.

I disagree. Consider the absurd example where every single statement is crammed into a single line. Not exactly readable to me?

Sometimes more verbose code is more readable, and sometimes it is the presentation, and sometimes this is "superfluous lines", that increase LOC.

Re: Avoid Else, Return Early (2013)

#128
post #103

I've been slowly trying to get back into hobby/side development after not being a professional developer for 11 years. Even when I was a full-time developer, I was never really in a "junior" role or dropped into an existing, quality codebase, so much of what I was doing was from scratch. Although my coding did improve as our team grew and it forced me to be more disciplined, I never learned a lot of little hints like…

I would strongly recommend Gary Bernhardt's Destroy All Software[0] screencasts. They're usually done in Ruby but independent from language, and more about concisely explaining general programming concepts.

Everything is crisp, and distilled down as far as possible. I've learned a lot just from the thoughts it has given names to and elaborated on.

If you're skeptical, there's even free trial episodes that you could give a shot first. (I would recommend "Functional core, imperative shell")

[0]: https://www.destroyallsoftware.com/screencasts

Re: Avoid Else, Return Early (2013)

#129

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

The problem with this is maintaining comments. If you are using a compiled language or even linting, code that is part of the codebased is checked by a machine at least in a cursory way and the code that is there is what runs. The comments are not guaranteed in any way to pertain to the code that is in the repo and there is not a way for a computer to check the meaning of the comment to make sure that it was updated to match the code. Comments can get out of date, which may make them do the opposite of what they are intended for.

Re: Avoid Else, Return Early (2013)

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

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.

The earlier version is clearly better and more clear, but presumes a language where if is an expression (and the actual return keyword isn't required, though “return if ...” is nearly as good.)

But if you are using a more imperative language where “if” is a statement, I think the merits of early return vs. use of an else clause are more balanced in this case.

Post reply on HN