Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

421–430 of 601 posts

Re: Avoid Else, Return Early (2013)

#421

Earlier quoted context omitted.

I've actually evolved a hybrid style in my personal projects - next line for functions/classes, same line for blocks. To me, it looks weird when functions don't have that extra line of space to set off their definition, but if/while/whatever aren't special enough to need that call out. That said, the most important factor is simple consistency. In my person projects, I have the hybrid style. At work, I use same-line-…

I think the Linux kernel style is similar. That was the first coding standard I somewhat adopted, but naturally have adapted to many others on different teams over time.

I think this style dates back to K&R C where you (maybe) declared argument types after the parens.

  int max(a, b) 
  double a, b;
  {
      return a > b ? a : b;
  }

Re: Avoid Else, Return Early (2013)

#422

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.

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…

A while back I tried to create a commenting system that explicitly tied comments to blocks of code. The idea was that if you tried to change the code without also changing the comment, or vis versa, a git pre-commit hook would yell at you. Unfortunately it wound up being less tractable than I anticipated, but I think the basic idea has some promise.

Re: Avoid Else, Return Early (2013)

#423

Mmm, I disagree. Influenced by functional programming, I prefer to use the style of: "keep all return statements at the same indentation level" in statement based languages. This way, it is easier to parse as an expression. For example: if (...) { let a = ...; return x(a); } else { return y; } Can be easily mentally factored into the pseudo-expression: return ... ? x(...) : y; It is easier to see what the side-effect…

Ah yes, writing a language in such a way that it helps you imagine it's another. Excellent coding practice!

Re: Avoid Else, Return Early (2013)

#424
post #166

Earlier quoted context omitted.

python fans are going like "what are braces?"

That's fine -- the Python folks have their own share of religious wars (starting with: tabs, or spaces?) :-)

The war is over. Py3 doesn't allow mixed spaces and tabs in the same file. You choose your side and never get to skirmish with the other one.

Re: Avoid Else, Return Early (2013)

#425
post #418
post #309

Earlier quoted context omitted.

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, YetAnotherLongParamT…

Emacs autoindent to the rescue:

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

Re: Avoid Else, Return Early (2013)

#426
post #166

Earlier quoted context omitted.

That's fine -- the Python folks have their own share of religious wars (starting with: tabs, or spaces?) :-)

Do they? All the Python folks I've ever seen express an opinion on style have said "follow PEP 8". Unsurprisingly, PEP 8 does have a rule for tabs vs. spaces: https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces (spaces, of course)

I love Python but as a long time C programmer I can't understand the preference for spaces in PEP 8.

Tabs are semantic and only take one key press for movement back and forth and to delete.

If you see 1 tab you know it meant one indentation level. With spaces you have to think.

Plus with spaces you are stuck with 2/4/8 spacing(unless you reformat), with tabs you can configure your editor to your preferences.

Re: Avoid Else, Return Early (2013)

#427

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…

Can you give some examples of replacing OO with dicts and lists? I've made classes or structs to make it easier to manage what a few associated lists/dicts were representing, but I'm not sure I've done the opposite. Maybe using lambdas instead of subclasses?

Re: Avoid Else, Return Early (2013)

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

Python specific IDEs will smartly indent code upon copy and paste.

Nope. Just try insert code formatter with 8 spaces into code formatted with 4, or 2. IDE will make something that compiles, it doesn't mean that it works properly.

Re: Avoid Else, Return Early (2013)

#429

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…

Some of theese are debatable and others, like set operations, are missing

Re: Avoid Else, Return Early (2013)

#430
post #192

Earlier quoted context omitted.

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.

No, you usually have to debug just as much, you just don't have any nice tools to do it with. I agree the monadic approach looks cleaner, but just be ready to undo it for any kind of hairy logic that requires debugging.

I have not found that and use it extensively. So, I respectfully disagree.

Debugging isn’t significantly harder, it’s a bit harder. In VS you can break on individual LINQ expression stages, read the unpacked values, read the let values, etc. If I’m composing with Bind functions then I can always break either inside the lambda or the static function being used for the bind operation.

Post reply on HN