Hacker News new | ask | show | jobs
by jbk 5019 days ago
> We also generally agree, in 2012, that goto is flat-out inappropriate for source code in most modern programs. Exceptions to this policy exist, but they’re extremely rare.

No, we don't agree. In C, goto is very often the best way to deal with error paths. It is used in the Linux kernel and in many other important (open source or not) applications. I doubt those qualify as rare.

4 comments

Agreed, for languages like C. It's not just error paths, either. For example, to break out of an outer loop inside an inner one you can label the outer loop with OUTER and use `last OUTER` in Perl or `break OUTER` in Java/JavaScript. But in C you have to either use a goto or (shudder) tinker with the outer loop control variable and break from the inner loop.
I like the position of this C2 article on goto: http://c2.com/cgi/wiki?GotoConsideredHarmful

It argues that forward gotos (that work like continue, break, returns mid-function) don't contribute to spaghetti code, while backward gotos are more problematic.

And yet backward goto is extremely useful. Consider this Java,

  redo: while(true) {
      for(Item x : xs)
          if(f(x))
              continue redo;
      break;
  }
With goto,

  redo:
  for(Item x : xs)
      if(f(x))
          goto redo;
Most people seem at first to balk at the goto, even though they're functionally identical, and the goto is much clearer and less error prone...
The article mentions that as well: "Backward gotos could be ok when it makes sense that your error case would repeat the last iteration"

Btw, in Ruby there are two keywords that are basically backward gotos: redo and retry.

That's the exact case where I saw it in the PostgreSQL code. Re-doing join pruning when a join was eliminated.
while (xs.Any(x => f(x))) { }

Pulling things out into other functions makes it even clearer.

Though yes, the goto is clearer than the labelled continue. I wouldn't necessarily agree that it's less error prone though.

Well, if we permit functional programming languages all the problems concerning imperative control flow magically go away...
I just used higher order functions to keep the example short, and I'd use them irl to avoid code repetition. The concept still applies without them:

    while (fTrueForAny(xs)) { }

    boolean fTrueForAny(List xs) {
      for (Item x : xs) {
        if (f(x)) {
          return true;
        }
      }

      return false;
    }
There isn't anything non-imperative about higher order functions.

    var externalDataStore = new ExternalDataStore()
    [1, 2, 3, 4].each(x => externalDataStore.store(x))
    externalDataStore.getItems().each(item => print(item))
Plenty of higher order functions, and plenty of non-functional, ordered, stateful, imperative code.
I would think that how localized the effect of the goto is would be far more important than whether it goes forward or back. Jumping back to the beginning of a function from the middle might be good. Jumping somewhere else, probably not so much.
Agreed, that wouldn't be too terrible, but then, again, I think that I always end up using a while loop for those cases when I have to "redo" stuff.
Well, C isn't a particularly modern language.
Yes, but a lot of software is written in C and continues to be written in C. There isn't really a replacement.
That's right.

I think the phrase is correct changing the word programs for languages.

It depends on the field of work.
Oo I agree, see my comment at the same time!