Live data from Hacker News

Goto (2007)

beej.us

161–170 of 207 posts

Re: Goto (2007)

#161

Probably coming too late to the discussion, but commenting anyway... The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time. Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks }…

My first job was writing VB.NET code and it was hammered to us not to use GOTO. Once for a critical production bug, using GOTO was the quickest solution to fix and I used it with a comment to not fire me. And that code lived on for years.

Sometimes a little bit of poison can make a great medicine.

Goes both ways though.

Re: Goto (2007)

#162
post #142

Earlier quoted context omitted.

You are correct, will edit. C is hard, writing C in the browser sans coffee is harder. :-)

I do think this illustrates one of the issues with goto: normally the compiler would be able to warn that you were using buf2 potentially uninitialized, but I think you wouldn't get a warning in this case.

One of the examples in the linked article showed the compiler emitting a warning when a variable wasn't initialized because the goto skipped past that line, it's in 31.7. I don't know what compilers will or will not give you that warning, but at least the one used for the article does. So it ought to catch the problem with the initial version of the example above as well.

Re: Goto (2007)

#163

Probably coming too late to the discussion, but commenting anyway... The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time. Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks }…

Can you give an example of where you've used goto in C or a C-like language? Or a rough estimate of the number of times you've found goto to be the best solution? I agree with your post in principle, but in practice I can't think of a single example where I've used a goto that wasn't eventually refactored to something better that didn't have the goto. Edit: Probably the most common example (and one given early in the…

[deleted]

Re: Goto (2007)

#164
post #97

Earlier quoted context omitted.

Right. He was criticizing the version where one subroutine might jump into the middle of another subroutine. That sort of thing can make safely modifying the second subroutine require knowing if any of its labels are used elsewhere in the program. It is basically impossible to reason locally when developing like that, unless you first verify that the only uses are local. (Or have applied strict coding standards such…

There's setjmp() and longjmp()to do that :)

setjmp() and longjmp() only work upwards through the call stack. They're basically an awkward version of exceptions. You can't jump into a subroutine that isn't already executing with them.

Re: Goto (2007)

#165
Goto is a useful precursor for writing a tail recursive solution.

For instance, say we have a state machine for recognizing that the last four button presses were 1234.

   int keypad() // returns 1 if correct key is entered, otherwise loops forever
   {
      keypad:
        switch (getkey()) {
        case 1:
          goto got_1;
        default:
          goto keypad;
        }

      got_1:
        switch (getkey()) {
        case 2:
          goto got_2;
        case 1:
          goto got_1;
        default:
          goto keypad;
        }

      got_2:
        switch (getkey()) {
        case 3:
          goto got_3;
        case 1:
          goto got_1;
        default:
          goto keypad;
        }

      got_3:
        switch (getkey()) {
        case 4:
          return 1;
        case 1:
          goto got_1;
        default:
          goto keypad;
        }
   }
Now, refactor the same structure into tail calls. Now it's suddenly beyond reproach.

   int got_1();
   int got_2();
   int got_3();

   int keypad()
   {
      switch (getkey()) {
      case 1:
        return got_1();
      default:
        return keypad();
      }
   }

   int got_1()
   {
     switch (getkey()) {
     case 1:
       return got_1();
     case 2:
       return got_2();
     default:
       return keypad();
     }
   }

   int got_2()
   {
      switch (getkey()) {
      case 3:
        return got_3();
      case 1:
        return got_1();
      default:
        return keypad();
      }
   }

   int got_3()
   {
      switch (getkey()) {
      case 4:
        return 1;
      case 1:
        return got_1();
      default:
        return keypad();
      }
   }
You can refactor any flow control graph based on goto, with local variables, into a network of tail calling functions. The tail call graph is isomorphic to the goto: it's just as complex and hard to understand. Yet it has the virtue of being beyond the reproach of computer science academia.

Re: Goto (2007)

#166

Earlier quoted context omitted.

> and defer Which “defer”? The go panic/defer pair is, while structured differently, functionally equivalent to exceptions.

You use exceptions to clean up resources even when there are no errors? Why?

> You use exceptions to clean up resources even when there are no errors?

exception handling mechanisms (try/except/finally) are idiomatic for that in languages with them (try/finally, particularly, because it assures cleanup whether or not an unhandled exception occurred); defer offers equivalent power with slightly different structure; you don't need both for any purpose either will do.

Re: Goto (2007)

#167
post #4

Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"?

Likewise using local variables instead of global variables. The point of structured programming is that it's less flexible than gotos are. Decreasing the flexibility of programming constructs means that the reader has fewer possibilities to consider and hence makes the result easier to reason about.

Beyond structured programming you might have object oriented programming that uses restricted access to the object's members to enforce certain parities on them that make the object's behavior easier to reason about. Or functional programs that restrict the persistent mutable state and make programs easier to reason about in another way.

Re: Goto (2007)

#169

Earlier quoted context omitted.

I would disagree with defer being better than goto. Some people prefer it, but I think in a lot of ways it makes your control flow harder to see than just a few cleanup blocks at the end plus goto.

It's a tradeoff. defer in Go is more like a try/finally statement in other languages, there's a guarantee that the deferred code will run even when there's a panic in the intervening code: handler = open(something); defer close(handler); // something causing a panic Should be the same as: handler = open(something); try { // something causing an exception } finally { close(handler); } This is not necessarily true of g…

There is a huge difference in semantics with defer compared to RAII since defer is called at the end of the function while RAII is scope based. It's mostly the same except for if you want to use RAII in a loop.

Re: Goto (2007)

#170

I learned Basic in the 90s and there was no for, no while, no functions or procedures. Just ifs and goto. Its hard to structure a program just with goto and it's even harder to read it and understand the flow.

[deleted]
Post reply on HN