Irrefutable proof that gotos will not be helping the programmers of the future:
Reminiscent of the actual Cobol Tombstone:
http://ed-thelen.org/comp-hist/TheCompMusRep/TCMR-V13.html#COBOL
Can it be objectively proven that control-structure blocks are "better" than goto's? (regardless of personal preference)
MuAnswer. Better for what purpose?
That's part of the issue to discuss. Perhaps some background. Some have alleged that certain technologies are objectively better. The goto issue is used as a testing ground of proving techniques.
I've rarely seen people allege certain technologies are objectively better without providing implicitly or explicitly a 'purpose'. The proposed 'goto issue' remains an invalid testing ground until offered a similar basis.
I would say "Developer productivity", but I doubt that is specific enough for you. However, the topic intro is not the place to hash it out in my opinion.
- Most important point: default behavior of a code snippet is hard to know, since a goto can go anywhere.
- What do you mean by "default"? Code with lots of IF statemnts and flags can also make it tricky to see what's "ahead".
- {It would be nice if you didn't screw up this page with your thread mode bullets.}
- Now here is an example of unnecessary rudeness. You could have simply said, "Please move discussion below the bullet points." I would have gladly done it. Don't let your reptilian attack-mode instincts control how you say things.
- {An if or case statement by default goes downward. A procedure or function by default goes downward. These are all default behaviors. Even the exit, break, and continue statements are defaulted - they cannot be several different things all at once - which is what a goto/label combination can be. A default behavior is a form of useful restriction. And no one is saying that goto's should be banned - this page should be directed toward evidence against harmful goto's. As with Dijkstra's paper on the case against Goto, unfortunately a lot of people misinterpret the "case against it" to mean that ALL goto's should be banned as a religion. This is not the case.}
- Most goto's went downward also, as I recall. Thus, direction is not necessarily a difference maker.
- This lack of "default" behavior means goto's are more unpredictable and hard to follow when reading a snippet of code.
- How is "unpredictable" being measured?
- {You admitted yourself further down that it is more predictable, and now you are asking how it is unpredictable? Look at your own words.. obviously you think so yourself - the measurement therefore is empirically proven by YOUR own words}
- Please use a named reference, such as a PageAnchor.
- Assuming everyone makes errors (which is true in all observations thus far) the potential error for a 'goto' statement is the full collection of labels accessible from the goto statement's context (which, depending on the language and compiler, might be a single routine or the whole program). Thus, when dealing with common classes of 'goto' patterns (including loops), avoiding use of 'goto' can automatically avoid a variety of potential errors.
- This is not specific enough.
- (*Waves hands in front of your eyes in return and speaks in a low monotone*) Yes it is.. And I'll even offer a reasonable argument: If you write a language-supported loop, you have no risk of error figuring out which 'label' to go to at the end of the loop. If you use 'gotos', and there are two or more labels in context, then you have potential to choose the wrong one. Therefore a class of potential errors is prevented simply by avoiding use of goto. QED.
- That assumes that using blocks has no downsides.
- No, it doesn't.
- Further, there's often confusion about which closing "}" a loop ends with. An explicit and unique name eliminates this problem. If not for the indentation, it would be very difficult. Again, I am not necessarily disagreeing from a personal perspective, but cannot turn my preferences into something outside my mind. A different person or alien may prefer something different.
- One can have named loops that require a name at the top and bottom be equal if one wishes it in a language, and it still avoids the class of error associated with 'goto' labels (since it would still syntactically prevent overlapping of loops). You're attempting to use 'preferences' as an argument against hard facts that come from the very top of the EvidenceTotemPole. Is this your normal modus operandi?
- If the block names are generic, such as "end-if", then one IF block ender can still be confused for another IF-block ender.
- That's ultimately irrelevant. One is still prevented from making a mistake. 'Confusion' and such subjective purely-inside-the-programmer issues are entirely irrelevant to the above argument, which regards only degrees of freedom to make actual errors and the observed truth that people, given enough opportunities, make every error they have freedom to make.
- If we "repair" it by introducing unique labels, then we create many of the same name-space problems that goto's have. It's a matter of trading context for unique naming in order to match and identify things.
- That's simply false. If, for example, you have named "if" blocks with named end-if pairs, you'll still be unable to end-if the incorrect 'if' statement due to the required block structuring of the 'if' statements - that is: one fully within another. If you write the incorrect end-if name, it will be caught at parse time - or even edit-time with a highlighting editor. You can't say the same of gotos.
- I have my preference, but this is not about personal preference. WaterbedTheory is popping up here between context and unique labels. Braces are the far end of context-only, block-type markers (end-if, end-while, etc.) are a compromise between these, and labels-only are the far end of this. --top
- The 'confusion' issue was never a counter-argument for the degrees-of-freedom problem... even confusing '}' statements still prevent the errors associated with the gotos. Aiming at confusion is a separate issue.
- May I suggest you provide examples.
- Also, given a 'goto' label in a large 'goto' context, it is rarely clear at a glance how one might reach it and, in the presence of errors, how one is intended to reach it - i.e. even if you're looking right at the error, it will be difficult (as a maintainer) to recognize it as one. The difficulties resulting from this have been observed often enough to receive a pattern name: SpaghettiCode.
- Same can be true with lots of flags and IF statements. Reduction of goto's often results in more flags and more IF statements. Even though the "statement pointer" may flow in a more predictable manner, the results of flags and conditionals still adds a lot of uncertainty.
- Oh! Oh! And I can pound a nail in with a hammer a lot more efficiently than you can drill a screw in with your tongue! Essentially, you're arguing that X done well is better than Y done badly, which is not particularly enlightening or valuable. If you translate the 'if' pattern to 'gotos' or labeled branches, the same problems will exist (you still need to conditionally hit all the correct segments of code) coming free with all the additional confusion regarding the branch labels. There are some resource-cleanup-patterns (in event of errors) that use gotos cleanly where 'if' based approaches are horribly obtuse, and I suspect you might be referring to these. But there are many other efficient patterns that don't use gotos (RAII, 'finally' clauses, 'withFile' routines, etc.). Mostly, one can make a good case against the use of 'IF' statements in the context of resource-cleanup and such, because that is 'ifs done badly'.
- I suggest you break this up into sections, with an example each. There's too much mixed up together in that paragraph to easily follow and reply to cleanly.
- Using 'goto' when you really mean 'foreach' or 'until' is semantic noise - you aren't expressing exactly what you mean. Long experience with languages of all varieties has proven that not saying what you mean introduces greater potential for confusion among people who read the code, including maintainers. Maintainers will need to learn to recognize patterns of code that vaguely correspond to a purpose rather than seeing some sort of language-statement or macros that makes its purpose as clear as possible.
- Create a label called "for-each". Just because Fortran used numbers as labels does not mean that all goto's should.
- And that fixes the problem how? 'goto foreach'... doesn't quite catch my meaning either, and 'goto until' is even worse.
- Just because you can? There's another point against Goto's: programmers who use clever tricks just because they can, should be banned from programming. Goto's offer these tricks to programmers who want to follow the "just because I can" style.
- If true, isn't that a psychological issue? Further, every technique is abusable.
- Using 'goto' with naive macro systems to create language-statements generally runs headlong into namespace problems (symbol conflicts for 'goto' labels) when need arises to nest macros, so you rarely have that choice in modern languages. That might change in the future, but it's a truth that exists today.
- Semantic noise can also affects other readers of the language: compilers, interpreters, and optimizers... e.g. use of 'goto' in place of a subroutine call makes it much more difficult to verify whether inlining of the call can legally be performed.
- This is an issue of inlining versus subroutines, not so much goto's versus blocks.
- Not really. It is an issue of semantic noise in general; the use of 'goto' in place of a subroutine is just one example. I could also talk about unrolling of loops and a variety of other patterns where hand-inlining 'goto' and other low-level implementation of a high-level ideas makes (more) difficult the analysis necessary to validate automated optimizations. This is fundamental because optimizations depend on finding invariants and high-level ideas are essentially abstractions of invariants and thus make them quite obvious to the analysis. But that really isn't the subject of this page.
- Can we agree to limit this to blocks-versus-goto's and exclude the issue of subroutines? I don't want to introduce any more factors than we need to. Further, subroutines or functions were readily available in most early 2nd-generation languages. --top
- I don't believe that a reasonable request, unless you're aiming to limit this page to: ObjectiveEvidenceAgainstGotosButIgnoringVariousFactorsArbitrarilyChosenByTop?.
- It's not "arbitrary", it's based on what actually happened in history. That code is available for analysis. A subroutine-free era never actually existed. And why would your choice be any less arbitrary?
- If statements and blocks have been around since Fortran and Lisp - the first two programming languages. Should we ignore evidence against gotos associated with these, too? You're making arbitrary decisions "based on what actually happened in history". Your excuses don't change that.
- IIRC, Fortran and COBOL (the most widely-used 2nd-gen languages until the 80's) did not introduce blocks until the mid 70's, but it took a while before those became widely used. Thus, we have about 20-25 years of wide goto usage. I've seen such code with my own eyes. The biggest problem I see with eliminating subroutines for the comparison is that the issue of subroutines/functs versus no sub/functs may become the overriding factor of any metrics, and we couldn't really tell. We are testing goto's here, not subroutines, and making subroutines the focus is arguably off-topic. If you wish to ignore this line of reasoning and continue on your way, may I ask that you at least separate the two lines of comparisons because I do not wish to participate in a subroutine-versus-no-subroutine debate. Lisp was not widely used.
- Feh. You talk as though evidence against gotos in one case would be a deciding 'metric' for policy regarding gotos in all other places. How extremely illogical.
- I don't know how you are coming to this conclusion.
- In any case, you bring up pages like this because you are convinced that there is no objective proof to support any methodology over another, which would include use of subroutines over gotos (and vice versa). I find your attempting to delimit the scope of evidence to be inconsistent with your prior assertions.
- If you wish to talk about objective evidence for subroutines, that's fine, but I'd strongly suggest creating a new topic for it. This one is about goto's. (I won't promise I'd participate in it, by the way.)
Most of the above are generalized thought experiments, not rigorous counts.
- Most of your responses, including that one, can be properly characterized as rigorous hand-waving, not reasonable counterpoints. 'Objective evidence' doesn't mean 'counts' or even 'measures'. It means 'not subjective evidence'. Logical inference in accordance with rules that aren't subject to arbitrary hand-waving is not subjective. Using rules that have traditionally lead to correct answers in the past, such as classical logic, is (in addition to being 'not subjective) even useful and well proven... and can even be rigorous.
- An example of something concrete and objective[1] would be CodeChangeImpactAnalysis. We would have numbers and know how those numbers came about. It may produce a result such as, "the goto version required 22 percent more lines-of-code being changed."
- If you wish to produce your own artificial soviet-shoe-factory problem by measuring the irrelevant, go ahead.
- Why is it irrelevant? I agree it is not thorough, for it is one metric among many, like say rebounding stats in Basketball. (Stat-based selection has proven superior in Baseball over scouting according to the book Super-Crunchers.) The Soviet example didn't use a bad metric, just not enough metrics. Your choice of the word "artificial" also is confusing. And, what numeric metric *do* you propose instead?
- In any case, CodeChangeImpactAnalysis itself isn't particularly relevant to the question of evidence for and against 'gotos'. CodeChangeImpactAnalysis is something you do either after you have a codebase or when you're deciding upon a codebase architecture in the presence of foreseeable need for change. That doesn't exist here, so the most you'll do with your acclaimed CodeChangeImpactAnalysis here is wave your arms some more, create 'code' and 'change' scenarios that favor whichever changes you happen to want to favor (probably using the 'X done well vs. Y done poorly' approach to building straw-men), then make whichever conclusion you happen to desire.
- It is my personal assessment that you are likely projecting.
- It is my personal assessment that you are likely incorrect.
[1] Some may argue that the choice of tests is subjective, but at least how the numbers come about is objective.
It doesn't matter whether they were motivated for subjective reasons; every choice you ever make is objective.
The above clearly shows a) how difficult it is to make general statements and b) how easy it is to uselessly criticize them.
The first poster should have clearly delimited his context. Given no context allows all kinds of counterpoints even ones that are silly and unhelpful. The first poster could have written:
- Comparison of GoTo against structured means to express looping with respect to readability of the expressed loop.
Probably nobody would have disagreed with the finding that
GoTo is worse at this task.
One could then list more uses of GoTo and probably find more areas where GoTo is not that useful (e.g. conditionals).
But an exhaustive list of GoTo usages is hard to get (though I bet there are disertations about this out there). I have no difficulty giving examples where a GoTo is more readable than the normal structured means. First among these being a simple StateMachine simulation. Every solution that decomposes this into loop+switch or lots of state classes or using recursion is inherently less readable and the state-transitions are more difficult to follow.
This quickly leans to the conclusion that GoTo is not inherently evil but - as always - the usage is. No GoldenHammer, but no TracelessPoison? either.
More involved and heated discussion about goto evidence in ObjectiveEvidenceAgainstGotosDiscussion.
See also: GotoConsideredHarmful, BickeringConsideredHarmful
CategoryMetrics, CategoryBranchingAndFlow
JuneZeroEight