Live data from Hacker News

Avoid Else, Return Early (2013)

blog.timoxley.com

491–500 of 601 posts

Re: Avoid Else, Return Early (2013)

#491

Earlier quoted context omitted.

It's right next to the create code, not 'spilled all over the codebase'. And if you really want different behavior on destruction (which is _really_ rare IMO), you can pass a destruction strategy at object construction. If you don't know how you want to destroy something when you construct it, you need to take a step back and reexamine your architecture.

And the create code is spilled over the codebase, just as well :-). It's not where actual work is done. This approach of encapsulating functionality in a class may work in some instances such as std::vector but more often than not it's just a lot of (typical OOP) boilerplate for things that you do only once in a codebase anyway. Giving one-off things a type and a name and decoupling them from normal control flow (rip…

I mean, having global resource managers is orthogonal to generating the events that cause resource destruction. And you're not 'ripping them out of context's, since the guard objects are still there where you would be doing the resource management manually.

EDIT: and I was the lead for a high availability C++ RTOS. I know that not all patterns fit for writing quality, available code. This fits remarkably well though. Even though we were totally async and didn't rely on the stack for context lifetimes.

Re: Avoid Else, Return Early (2013)

#492
post #252
post #106

Earlier quoted context omitted.

> Same way braces go on the end of the method/class name to reduce LOC. Screw that. I've been writing code for 15 years, and Allman style braces make it so much easier to mentally parse code into blocks that they're worth every single LOC. I can't speak for anyone else but I'm not working on an 80x24 terminal anymore.

I used Python enough that braces are completely meaningless to me in languages with them (ie, everyone else). Indentation is my mental delineation of code blocks. I just have to write these {} things all over the place because every other language is a gramatically bloated mess. The advent of automatic code formatting (and Python pioneered this in many ways with pep8, but even huge C++ projects are realizing the valu…

> I just have to write these {} things all over the place because every other language is a gramatically bloated mess.

In what way are context-free languages "a grammatically bloated mess?" Whitespace delimited languages like Python have context-sensitive grammars. Now that is a mess.

Re: Avoid Else, Return Early (2013)

#493

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 you go more composition instead of inheritance.

What does that mean?

Re: Avoid Else, Return Early (2013)

#494
post #465

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 you move on from heavy OO to dicts/lists. Is that a thing? No question that many concepts of OOP are in heavy need of reform, but I didn't know the basic idea of a struct was one of them. I can sort of imagine this for quick-and-dirty things in untyped languages - but if you have types, passing dicts around everywhere seems like needlessly throwing away type safety - while it's also cumbersome to code and…

I think this might partially be related to the move towards streaming applications and microservices. You could create objects for everything you expect to receive/send and then when an API changes you lose the new fields, you get parse errors, etc. If you did it right maybe you can avoid some of those things, but the bottom line is that type safety is a little bit too strong a constraint for these use cases.

Even if I'm getting from a DB which won't be changing out from under me, many times I'd prefer just getting a simple Map rather than spending time creating a "safe" object. Do I create a User and UserWithDetails? Or always return UserWithDetails but sometimes fields are empty because I don't care about them? Dicts are light, objects are cumbersome.

Re: Avoid Else, Return Early (2013)

#495

Earlier quoted context omitted.

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

Quite interesting. For a moment I've thought it is another JS issue but no. It's React who's strange https://github.com/facebook/react/blob/v0.11.2/src/browser/u... https://github.com/facebook/react/blob/v0.11.2/src/utils/tra...

Same behavior on Ruby:

    def content_markup(children)
      case children
      when String, Numeric
        children
      when NilClass, TrueClass, FalseClass
        return
      else
        # ...
      end
    end

    content_markup 'foo'
    #=> "foo"
    content_markup 0
    #=> 0
    content_markup true
    #=> nil
    content_markup false
    #=> nil
    content_markup nil
    #=> nil

Re: Avoid Else, Return Early (2013)

#496
How is it that articles like this not only get written, but get voted onto the front page of HN? It's not that the content is bad but that the content has been presented elsewhere, and numerous times, e.g. c2 wiki.

Is it because we're not really engineers? We're just hackers? I feel like I've seen this discussion every five or ten years or so. Is that just my perception, or do we have waves of interest and knowledge building and then loose it all in some exodus from the industry every ten years that I'm not aware of? One of the threads here ended up exploding into yet another coding style "discussion", the kind I first remember back in 1995, and my attitude hasn't changed since then (just pick one and move forward).

I can only imagine that as soon as B[1] was created, programmers started arguing about whether or not the curly brace should go on a new line.

And that's the real problem here. We are still attempting massive engineering works using the tools of 1969: text files. We have graphical tools with automated assistants for finance, medicine, space flight, car design, but when it comes to the software that we programmers use to create that other software, it's 1969 text files with curly braces. No fucking wonder I keep seeing the same old shit. We should be in outer space right now, but we're still teaching the kids how to hold the sticks to make fucking fire.

[0] http://wiki.c2.com/?SingleFunctionExitPoint

[1] https://en.wikipedia.org/wiki/B_(programming_language)

Re: Avoid Else, Return Early (2013)

#497
post #149

Earlier quoted context omitted.

Yeah, I’ll file that under “maybe don’t do that”.

what are the downsides

In general terms, in C-like languages, mixing braces and semi-colons is horribly refactor unfriendly and bug prone. Meanwhile, sticking things on one line introduces a cognitive load that you might not want. (YMMV on the second point, but I’ve pretty strong views on the first.)

Re: Avoid Else, Return Early (2013)

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

And a good name for the bad style is Arrow Anti-Pattern[1]

This article also discusses the solutions (there's a lot of overlap with OP's article).

http://wiki.c2.com/?ArrowAntiPattern

Re: Avoid Else, Return Early (2013)

#499

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 was just cargo cult programming as far as I could see where what one senior developer said was taken as gospel. I tried arguing objectively against practices like this and several others but was ignored.

It was so bad, I remember one time some of the junior programmers literally shaking their heads when they saw some functional programming language examples for the first time because multiple returns are idiomatic there. They couldn't explain why multiple returns were bad, just that they were bad.

I don't find this uncommon though and understanding it's a time saving heuristic. People will accept a "best practice" from an authoritative source without question and only later start thinking about it objectively when it gets in their way somehow.

If your team is ignoring objective arguments though then you're in a cargo cult.

Re: Avoid Else, Return Early (2013)

#500

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.

Source control, eg the "comment" when committing code can also be used for comments.
Post reply on HN