News for hackers. Stuff that matters.
Re:Loop Exits and Structured Programming: Reopening the Deba... by glangdale on Monday June 12, 2017 @06:26PM (#14541615)
Goto gets a bad rap, and I have seen many programs where an explicit goto, to a label that is descriptive, is way clearer (and less brittle under reorganization) than a 'structured' break or continue - or some spaghetti of booleans (while (!done) ... ).

It's clearly very easy to write bad code in many ways, but (very) judicious use of goto is occasionally far clearer than assuming goto is always bad and building something complex out of bools, break and continue. It seems to be a test of common sense: if goto is clearer than the alternative, use goto.

Re:Loop Exits and Structured Programming: Reopening the Deba... by userbinator on Monday June 12, 2017 @10:25PM (#14542512)
I've been programming for a long time, and have come to the conclusion that "structured programming", then "object-oriented programming", and now "functional programming" --- and whatever comes next --- are all manifestations of dogma: "best practices" that someone obviously thought was a good idea to solve many problems, but not all. The difference between "many" and "all" is where these "best practices" turn into horrible common-sense-violating abominations.

I think programming should really be taught starting with Asm, and thus, a language where gotos are the norm. Flowcharting should be considered an essential skill for designing and describing algorithms. Control structures like if/else, do/while, while, for, etc. should be taught as abstractions that are to be used where it would simplify the code (much like all abstractions should be used for), but if your algorithm doesn't fit these structures 100%, it's better to use gotos than to try to "force" it to fit by creating a "spaghetti of booleans".

State machines are another use-case where goto makes perfect sense: instead of storing state in additional variables, the current position in the code is enough. It makes debugging much easier when you are actually jumping between the states as you step through the code, rather than looping back up into a switch or a series of if/else checks on another variable.

Re:Loop Exits and Structured Programming: Reopening the Deba... by mcguire on Monday June 12, 2017 @09:26PM (#14542360)
In one paper on the structured programming issue, Don Knuth has a beautiful axiomatization of goto by Tony Hoare: https://maniagnosis.crsr.net/2011/11/link-o-day-donald-knuth...
Re:Loop Exits and Structured Programming: Reopening the Deba... by dbaupp on Monday June 12, 2017 @09:43PM (#14542400)
Your specific example sounds like the kind of thing addressed by more powerful structure: labelled break, as appears in Java, JS, Rust and Swift (among others, I'm sure).

Of course, thinking about labelled break is just dreaming when required/choosing to work in a language without it.

Re:Loop Exits and Structured Programming: Reopening the Deba... by sedachv on Monday June 12, 2017 @10:47PM (#14542571)
Labelled break is strictly less powerful than gotos, and IMO its implementation in Java is far inferior to the block Common Lisp special form (https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node85.html) because s-expressions make the lexical scoping unambiguously visible.

IMO there is no good substitute for gotos when writing transpilers (and certain interpreters) and low-level concurrency code. The Common Lisp prog macro is the best way that I have seen to use gotos (https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node91.html).

Re:Loop Exits and Structured Programming: Reopening the Deba... by dbaupp on Tuesday June 13, 2017 @12:11AM (#14542813)
Of course it is strictly less powerful than gotos. That's actually the point of the more structured constructs: they are more restrictive and so can be reasoned about more easily. Note that I'm specifically piking up on labelled break/continue as a substitute for nested loops like the following

  while ... {
    bool shouldBreakOuter = false;
    while ... { ... shouldBreakOuter = true; break; }
    if (shouldBreakOuter) break;
  }
since that what the original comments description sounded like. Being a rather general control flow mechanism, there are of course other uses of goto which this doesn't cover.

That said, I'm not sure I understand the comparison: the lexical scoping doesn't seem to be ambiguous in Java. Could you expand on what you mean?

Re:Loop Exits and Structured Programming: Reopening the Deba... by sedachv on Tuesday June 13, 2017 @01:34AM (#14543025)
If you visualize nested scopes as indent levels, the labelXYZ: sits in an indent level above where it is visible. Not only that, but labelXYZ: does not come before the statement that it transfers control to, but two statements before. If all that was not bad enough, most people format the labeled statement to sit at the same indentation level. The combination of these three things is pretty much the worst possible when it comes to reading code. Compare this to block/tagbody/prog and their indentation conventions in Common Lisp.
Re:Loop Exits and Structured Programming: Reopening the Deba... by userbinator on Monday June 12, 2017 @10:27PM (#14542518)
Unfortunately, in my experience the abuse of labelled breaks to avoid gotos tends to be even worse than abuse of regular breaks, since the label no longer shows immediately where the flow goes; it only labels the start of the block, when what you really want to see is the end.
Re:Loop Exits and Structured Programming: Reopening the Deba... by dbaupp on Tuesday June 13, 2017 @12:14AM (#14542823)
I guess that could indeed be annoying for reading code, especially if the labelled block/loop is very long (I personally usually end up using these for short nested loops, longer loops usually get broken out into separate functions, and the biggest teams/programs I've worked on haven't been using languages that have this feature). That said, the extra structure/more restrictions of labelled breaks lends itself to compilers and other tooling being more helpful, both for optimisations (although SSA + basic blocks that most compilers now use makes this somewhat irrelevant) and for catching mistakes while, for instance, refactoring.

In any case, I strongly disagree that labelled breaks aren't better than regular breaks: the chains of booleans required otherwise are very annoying and error prone.

Re:Loop Exits and Structured Programming: Reopening the Deba... by nickpsecurity on Monday June 12, 2017 @10:19PM (#14542495)
It's why some of us built 4GL's, DSL's, preprocessors, and so on that added stuff to such languages but extracted to purely that language. Mine was a BASIC with macros translated to C w/ safety checks.
Re:Loop Exits and Structured Programming: Reopening the Deba... by mjevans on Monday June 12, 2017 @10:15PM (#14542484)
goto is best viewed as a low level (unsafe) operation.

I wouldn't mind it if the language expressly made me call such a function from a library of other 'unsafe' operations. Optional things that you can include when you really know what you're doing and use them in a limited way.

It's one of those tools that is powerful, dangerous, and best avoided when another will suffice. Yet like explosives, sometimes dangerous is the best tool for a job.

In the case of a programming language goto can be used to emulate features and/or paradigms that a language doesn't have or doesn't quite do sufficiently. It should ALWAYS have a comment that annotates the intent.

Re:Loop Exits and Structured Programming: Reopening the Deba... by dingo_bat on Monday June 12, 2017 @10:31PM (#14542532)
How is goto an inherently unsafe operation? As long as the usage is clear, it's as safe as any other logical instruction. Problems pop up when nobody else is able to read your code and fix a bug. I feel bad because it has been drilled into my head from the start that goto is unconditionally bad. So I never use it. But I saw a friend replace my spaghetti jungle of break and continue with a simple and clear flow using goto. It was a real mind blowing moment.
Re:Loop Exits and Structured Programming: Reopening the Deba... by mjevans on Monday June 12, 2017 @11:01PM (#14542607)
It's 'unsafe' like how working with raw pointer arithmetic is 'unsafe'. It escapes the paradigms offered to provide regular flow and might also require the compiler to restrict how it handles those sections of code. As others have pointed out elsewhere, it also affects how humans interpret the code, thus it is more likely to be related to bugs as well.
Re:Loop Exits and Structured Programming: Reopening the Deba... by glangdale on Tuesday June 13, 2017 @07:05PM (#14549419)
It is not remotely unsafe the way that raw pointer arithmetic is unsafe. Proving things about what raw pointer arithmetic winds up doing is undecidable; non-computed goto, on the other hand, is completely obvious. On the theory side, at worst you can create nasty irreducible flow-graphs where you can't simply put code on 'edges', but this is pretty minor. It is very unlikely that a compiler is going to go into the weeds from a local goto; you are spreading FUD.

Exceptions, on the other hand, or non-local goto, has a good chance of seriously scrozzling compilers and causing a lot of optimizations to go away.

All that being said, the potential to break human understanding of the code with gotos is serious.