OOP and GoTo
When computer science pioneer Edsger Dijkstra wrote his paper, "Go To Statement Considered Harmful," he created such controversy that the ACM - the group that published his paper in their journal - adopted a policy to never publish such strong opinions about programming style again.
Fortunately, we don't have to follow those rules here at About Visual Basic.
I've been amazed at the email I've received so quickly. I thought the world had pretty much learned by now that using GoTo in your code is about as bad as swearing in church. But I guess there are some holdouts. Hopefully, some of the people who wrote emails to me will post their thoughts as comments to this blog so we can all participate in the discussion.


Comments
Hi, Dan!
My personal favorite Dijkstra quote is from a conference we were at in
Munich in the ’60s, when he stood up in front of a polyglot audience and
announced “Programmers have, for years, been plagued by the monstrosity
of their tools!” … which left most of the Americans in the audience
gasping for breath.
But I take gentle issue with your interpretation of his intent with
respect to GoTo.
If you examine the generated code from almost any compiler, it is rife
with JMP commands or their equivalent. So I argue that at a *machine*
level, one cannot eliminate GoTos. Very well, then … what else could
have ED intended? I rather think that it was a warning concerning GoTos
*in documentation*, and hence, by extension, in higher-level languages.
A *warning*, not a prohibition.
Remember, I’m still using VB6, so I can’t speak to VB.NET … but VB6
still has “exit for”, “exit do”, and the like, that are, indeed,
disguised … and well-behaved … GoTos. Why are they acceptable?
Because both their intent and their extent are clear. Similarly, in C,
the *break* that is used in the *switch* statement is a well-behaved GoTo.
So ED’s argument is that *abuse* of the GoTo leads to catastrophies is,
I think, valid … but the extension to the *elimination* of GoTos is at
least weak. In the days of UNIVAC I we did a tremendous amount of
documentation before writing any code … and one of the important
“tricks” was to minimize the number of off-page connectors in the
flow-charts, for exactly the same reason that ED objected to GoTos …
they made following the logic difficult. So instead of off-page
connectors, we had “levels” of flow-charts, where a single box at one
level was a full page at the next level (and so on), with a naming
scheme for the boxes so that it was possible to trace from a single
machine instruction back to the highest-level flow-chart in an orderly way.
But think about it: what we were doing with the flow-charting process
was, in effect, the work that is now done by a compiler/linker/loader
… and, indeed, the resulting machine language needed to use GoTos all
over the place. (For the masochistically curious, I’ve written a UNIVAC
Simulator [in VB6] that is *very* realistic. See
http://www.ingerman.org/niche.htm for further details.)
So please, give Dijkstra full credit for what he said, but recognize
that it occurred in a context, rather than being an absolute statement
for all times and places!
Peter’s an old friend and frequent contributor to About Visual Basic. I’m “visually basically” green with envy when Peter says things like:
“from a conference we were at in Munich in the ’60s”
Ah Ja! Paris is so much nicer than Rio when the daffodils bloom!
I’m even more jealous when he tells me about actually knowing really great software pioneers like Dijkstra.
Anyway …
I think Peter understates the depth of Dijkstra’s opinion. Quoting from his original paper in the ACM:
… I became convinced that the go to statement should be abolished from all “higher level” programming languages (i.e. everything except, perhaps, plain machine code).
It’s hard to misinterpret “abolished”. He wasn’t giving us a “warning” about “documentation”. He wanted to stamp it out.
But Peter is absolutely correct about machine code and you can see that Dijkstra recognized that too. I left that out of the article because this site is about Visual Basic.
I have to softly remonstrate my good friend Peter about “exit for” and “exit do” as well.
The bad behavior of GoTo is due to the fact that it can send you to ANY part of the code and the state of the program and what will happen is just plain tough to predict when the program suddenly starts executing in the middle of some procedure eight pages away.
Exit For and Exit Do, Select Case, and all similar control statements branch to specific places within the current object. The state and behavior of the program is much easier to visualize.
And that’s what Dijkstra and I are talkin’ about!
I LOVE the rest of Peter’s message. In my article, I write about how difficult is was in the 1970’s to convince a senior Cobol programmer that GoTo was evil. Peter absolutely makes that vision jump up and dance! That’s exactly the kind of discussion I used to have. One of the consequences of creating programs with the software equivalent of cooked pasta is that (to quote Peter), “… we did a tremendous amount of documentation before writing any code …”
Not that this is bad. (I would never discourage documentation.) But my point is that the use of GoTo makes it absolutely essential because it introduces such horrible problems. You just can’t write spaghetti code without taking extraordinary measures to keep the logical twists and turns to a minimum.
Ah Ja! Them thar wuz the gud ol daze all righty! I’d love to go back to writing code on punched cards. Life just seemed to be more joyous then. But we can’t hold back the tide of progress and eliminating GoTo is a key part of that progress in software.
As this is thanks to me I guess I should have my two penneth worth.
A long long time ago when I was a lad I typed my first program thanks
To the wonderful book
SIXTY PROGRAMS
For the
SINCLAIR
ZX SPECTRUM
Here’s a small selection from one of them!
10 REM ** FLYING GEESE
20 GO TO 580
25 REM ** FLYING/SHOOT ROUTINE
30 FOR x=0 TO fr: LET d(x) = ei – x+SGN (o – tw* INT (RND*tw)):
PRINT AT h(x), g(x)-o;” “;: FOR z=o TO fr: LET f=-f: PRINT AT d
(x),g(x);” “; a$(th-f);: NEXT z
40 MORE CODE
50 MORE CODE
60 NEXT X: IF SH>90 THEN GO TO 300
70 GO TO 30
100 MORE CODE
110 MORE CODE
120 MORE CODE
130 MORE CODE
140 GO TO 30
etc, etc, etc
1040 DATA 0, 48, 16, 132, 33, 4, 81, 4, 160, 0
But time moves on and I upgraded to an Amiga 500 (Hooray!) this was state of the art, no more waiting for the Cassette tape to load the program, they had Floppy Disk.
And a new language to learn Amos.
Moving time on again the Amiga went belly up and I went over to windows.
And a new language Visual Basic right up to Version 6 then beggar me if Microsoft
Didn’t go and pull the rug from under me feet!
So time moves on once more and now I’m playing with
Visual Basic 2005.Net Express Edition
Why all the history? well that’s the point it’s History just like the GO TO command,
Time and technology have moved forward and so must we, bouncing around your code with GO TO here and then GO TO there is just not good programming.
I still think of myself as a beginner as I only ever play with languages for myself , a little hobby and nothing more.
But even I, as a Play Around Programmer can see the logic of dropping GO TO form the code I use in future.
Well, let’s see if I can’t make things either clearer or muddier!
On the one hand, I *do* agree with Dijkstra’s general position that GoTo should not be used in higher-level languages without *great* care and documentation, but I *don’t* agree with its being abolished completely.
When I program, I very rarely use a GoTo, but sometimes it’s the only way of getting the heck out of a nested bunch of errors … not in the sense of On Error, but simply because the logic has gotten out of hand for one reason or another, and it’s time to retrench.
But I see no difference between, say, “exit for” and GoTo except that the former is simply a well-behaved (and well-disguised!) GoTo … which makes my philosophical point that GoTo has *not* vanished from higher-level languages, it’s just better behaved when it’s wearing a mask.
As for documentation? I hope Dan will concur that the historical sequence went something like this:
a) Programmers documented first, and lots, and then finally coded, in machine language or something very close to machine language.
b) Higher-level languages (COBOL, Fortran) happened, and someone figured out that it was possible to write a program that would read in a program and develop a flow-chart from it. (I’m not sure whether I bless or curse the first Fortran programmer who wrote “FORMAT 80A1″, after which writing a Fortran compiler in Fortran became obvious.)
c) The machine-generated flow-charts mapped the *extent* of the program, but almost by definition were incapable of mapping the *intent* of the program, and hence fell into disuse because they weren’t helpful in the long run.
d) People like Don Knuth have been pushing for the concept of writing the documentation and then having *something* turn the documentation into a program.
e) A firm in England (sorry, the name escapes me at the moment) has developed a program-development language that allows a program to be tested for correctness as it is being implemented, which has the effect of doing the documentation first, the way the gods intended it should be done.
(And I still use a Gateway Anykey keyboard because the function keys that I use are on the left, where the gods intended them to be! I use the top ones for macros.)
So we’re offering to come full circle, or, maybe, full spiral. Specify the problem and explain why the specification is correct, then generate the program that solves the problem and assure that each step of the solution is both correct and consonant with the specification.
I remember the Gateway Anykey! I believe I used mine so much that I wore it out. Great keyboard!
I think the gods gave us “GoTo” to keep us confused so we wouldn’t become too powerful. Dijkstra is probably chained to the same rock with Prometheus for opening our eyes about it.
If a programmer can’t figure out hou to code a program without using go to, they need to be flogged fiercely about the head and shoulders. Flogged with what? Your choice. My feelings are: if you can’t figure a way of writing the program without using a go to, that piece of code shouldn’t be used.
How about “depending on go to? That is even uglier than a plain go to. Exit for and Exit sub, is still open for debate. But this discussion is about VB not Cobol or Fortran.
When Microsoft wrote the new VisualBasic, they left in (at least) two features, but modified so they don’t work right anymore. This is not unusual for Microsoft.
Please, dont say that GoTo is bad for programming. That is the myth. Instead, say there is a flaw in VB.NET that makes it misbehave when GoTo’s are used. It is a flaw in VB.NET. If people would start blaming MS for its shoddy engineering practices, maybe MS would come around to using better code (possibly eliminating the “gates” in Windows, and IE). But, we will never see this while responsible parties keep blaming independant programmers for MS’s bad code. The bad code is in the VB.NET program.
As you pointed out, GoTo was used millions of times BEFORE VB. Now, suddenly, it don’t work? Give us a break.
As for the disappearing text, MS has built yet another flaw into the code.
KrazyKyngeKorny
Gee, I thought we were talking about GoTos in whatever language?
I have myself to blame since I “opened the door” by taking a few pot shots at Microsoft and other languages myself. So I can’t blame others too much for walking through that door.
But I would much prefer that we keep the discussion focused to Visual Basic as much as possible.
As a company, Microsoft isn’t any more to blame than others in my experience. I’m disappointed in the way they have abandoned their VB6 developers, but in general, their systems work well and .NET in particular seems brilliant in spite of a minor flaw here and there.
(I’m reminded of my experience with IBM. OS 360 was the greatest technical achievement that had ever been done in software when it was introduced. And Fred Brooks, the manager at IBM most responsible for OS 360, continues to be my personal hero. That didn’t stop Microsoft from chewing up IBM with Windows a decade or so later. There is no technical achievement that programmers can create which can’t be thrown away by bad managers from the marketing side of the company.)
But I maintain that GoTo is a bad construct. That’s not a myth, it’s as close as you’re going to get to a proven law in software. The reason is that the human mind just can’t track program state when GoTo’s are present, a problem that just isn’t the same with “well behaved” constructs like Exit Sub that stay inside the boundaries of the current object.
Peter has a good point, and although Dan wants to focus on VB I think it is worth pointing out (since he did mention Cobol, et al) that what makes a practice a good idea or a bad idea in a particular language depends somewhat on the tools that language provides.
I started programming on NCR mainframes using a proprietary language called NEAT/3 (and later NEATVS), compiled language that allowed one to get down to the assembly level (which was similar to BAL). There were very few control transfer instructions available. Mostly, one had to use the equivalent of a GoTo. Even the equivalent of an If statement did not have control transfer built into it; it merely set flags indicating the outcome of a compare, and one then had to test them using conditional control transfer instructions.
Basic (including VB) and various other languages include If statements that inherently handle conditional control transfer, and looping constructs that inherently handle control trasfer for looping. The various versions of the Exit statements that Peter mentioned are forms of GoTo, but specific to their particular contexts. These tools allow for great flexibility in control transfer while maintaining readability.
The GoTo is, however, a generic control transfer statement that is independent of context. This makes it a powerful tool, but perhaps one that is too powerful. Like any powerful tool, it can cause a lot of havoc if misused.
When I was new to VB, I did resort to it on some occasions, but as I learned to more effectively use the other control transfer tools, I ceased to do so. Basically, there was no real reason to use a general tool when one or more of the of the specific tools did the job, simplified the code, and made it more readable.
Upshot: in VB, I agree that using GoTo is, if not actually a bad idea, at least an unnecessary one.
And a good day to you, Dale!
Let me suggest another way of looking at the GoTo issue.
In the early languages, branching was generally of the form
If [condition] then [transfer control]
I include under this Dale’s mention of setting a flag that gets tested later (with something like the above), and it’s clearly the same as the Fortran
If [arithmetic expression] [negative][zero][positive]
Perhaps one of the major developments in programming languages was the notion of parentheses … not just the obvious “(” and “)” used to group in arithmetic and logical expressions, but the notion of parentheses that enclosed pieces of code, so that from outside, they looked like single “statements”, and from inside, one couldn’t see outside.
With respect to the “If” statement (since I started with it), this meant introducing constructs like
If … then … else
and
If … elseif … elseif ……. else
which reduced, if not eliminated, the need for GoTos to deal with chunks of code that weren’t to be executed this time through.
Note that the GoTo-ness is still there, but it’s controlled and implicit.
In VB, the Do … Loop construct clearly contains an implicit GoTo that is well-behaved, and adding the Exit Do is simply allowing for another well-behaved GoTo.
And so on.
So languages have developed in a way that allows constrained GoTos whose behavior can be followed and understood, providing the scoping rules are clearly understood.
But every once in a while (and surely not as often as every twice in a while!) a GoTo is the simplest solution to a logic problem, and I, for one, would not be happy seeing it eliminated in its entirety. Yes, it can be abused … I try not to. Yes, it can be confusing … but if one doesn’t understand it, one should avoid using it. And the possibility exists of a language with sufficient well-behaved implicit GoTos so that an explicit GoTo is unnecessary, but I don’t think we’re there yet.
Oops … sorry about the bad HTML!!!
Go To or GOTO is was and will forever remain a most useful and powerful programming tool when used appropriately by skilled programmers.
Maintaining 30-40 year old systems without using GO TO in COBOL would require program rewrites that just aren’t worth the time.
Ten and twelve thousand line Microfocus PC Cobol programs with conversational field-by-field dialogs would seem impossible to code without “Go To’s, based on my current job experiences.
I learned the “structured” methodology thirty years ago, and wrote “Go To-less”
programs for the “enlightened” clients who considered “Go To” a high crime of some kind.
So I would code an extra paragraph or two to avoid a “GO TO NNN-EXIT” from a PERFORM NNN THRU NNN-EXIT routine, so as to placate the whiners and other superior beings who demanded this purity
due to one guy’s opinion in an article.
I’ll readily admit that “GO TO’s” used frequently,recklessly, and wantonly, without knowledge and care, lead to really crappy coding,likelihood of errors, and difficulty in modifying code.
And I have worked on and cleaned up many such coding messes in thirty years.
But wise and judicious use is nothing but helpful.
I ended up here because I’m learning Javascript, and on an Inquiry function, I’d like to go around a huge pile of validation logic for Add and Change functions to a label beyond these edits.
If (select==”I”)
goto myLabel
else
{do this huge pile of stuff that folows}
I’m Javasript ignorant unfortunately, and still trying to teach myself.
I’ve been hearing this silly argument for 30 years now. “GO TO’s” are a very valuable tool when used appropriately.
There, I’ve said it. Long live the GOTO!
Michael King
If GOTO is bad, how about the new RETURN in VB.NET, which immediately breaks out of a function? I mean one expects a structured function to have exactly one entry and one exit. With the new RETURN you can jump out of a function at any place, as often as you want. RETURN is even more powerful than GOTO (and possibly more dangerous too). GOTO is always local in VB, it never jumps into another function.
I hope it’s OK to mention
Project Analyzer here. It’s a tool that searches VB code for GOTO, ON..GOTO, EXIT, RETURN and other “questionable” statements, in case you feel they shouldn’t be used in your own code. I don’t mean you should never use them, but maybe it’s better to avoid them when you can.
To Mike …
To each his own. When I used to write Assembly Language subroutines, I would sometimes reserve a hundred bytes of memory at the end of the program, branch to it just after critical routines, and code a return inside the reserved storage. That way, I could write a machine code subroutine inside the reserved space if I ever needed to and patch memory to install it.
Those were the good old days. I don’t do that anymore.
You said one thing I do agree with:
“Maintaining 30-40 year old systems without using GO TO in COBOL would require program rewrites that just aren’t worth the time.”
I used to supervise a group of Cobol maintenance programmers and I know what you’re saying. In my opinion, a good maintenance programmer who can wrap his or her mind around the mind numbing complexities raised by Go To is a real software hero. It really does cost millions to rewrite that old code. A company I worked for once tried to rewrite their main customer accounting application THREE TIMES in about a 20 year time span and failed every time at a total cost of probably 10 or 15 million dollars. There’s a reason those old programs can still be found.
But that doesn’t make Go To a good programming technique. It just makes it a necessary evil sometimes.
To Aivosto …
I’m not sure I understand what you’re trying to say.
First, the Return statement in VB.NET is just one (of many) little improvements that save a line of code here and there. In VB 6, you had to code it this way:
Private Sub Command1_Click()
MsgBox (TestReturn())
End Sub
Private Function TestReturn() As String
TestReturn = “Get Out Now”
Exit Function
MsgBox (”This statement will never be executed”)
End Function
But in VB.NET, they added the Return statement that just lets you do the same thing in one statement.
Private Sub Button1_Click(…) Handles Button1.Click
MsgBox(TestReturn())
End Sub
Private Function TestReturn() As String
Return “Get Out Now”
MsgBox(”This statement will never be executed”)
End Function
But it’s really clear that I didn’t communicate successfully about why Go To is a bad idea. Return always goes back to the statement following the function call. Go To can go anywhere.
Your statement that an object should have one entrance and one exit is a principal that SOME OOP programmers do try to follow. Return (and the related Continue which you did not mention) do violate that rule. But since they only allow part of the function (or loop) to be skipped, they don’t create the complexity caused by execution suddenly starting at some completely different part of the program. Execution resumes only at the statment following the original call! It’s a whole different paradigm.
ps … Sure – It’s OK to recommend things here. It’s not OK to blatently pitch your own commercial enterprise.
I was prepared to send a perfectly good example of when and why GoTo can be somewhat appropriate. I had to look for a long time to find the 10 year old code, but find it I did. Only to discover that I had rewritten it to no longer use the GoTo (it might have been a GoSub). Darn!
In any event, I still use it because I think the Try,,Catch crap is just that. Mine still looks like it did in much of my VB 6 code. It can easily be more functional than the little bit of code below.
I am prepared to take whatever flack I get from this.
On Error GoTo EH
‘ some code
‘ some more code
EH:
Select Case Err.Number
Case 0
‘ Set return values or whatever
Case Else
Dim sMsg as String = ErrorText(”ThisRoutine.Name”)
Err.Clear
LogMessage(sMsg)
End Select
This is absolutely wonderful!
I’m at a point now where I wonder why anyone ever thought GoTo was a good idea (even though I wrote a LOT of spaghetti code myself back in the day). And then along comes a post like this one from Tom to remind me!
One company I worked for actually had an internal standard, built entirely around GoTo, that programmers were required to use for reading records from a sequential file. (They called it the Blooey Tube.)
Such is the nature of progress. There are people today who argue that the Earth really is flat.
I read all of these comments with much of it going over my head, well, not as much as you might think. One thing that I was glad to see and it came right from the Microsoft mouths…that they are supporting product for a full 10 years, not just 5 years as they had originally conspired to do. I’ll have to find that article now but it was just in this past week, I think in Eweek, about their latest claim of 10 years support for all of their products. I think that VB6 now will have support for that 10 year range so all is not completely lost just yet. I just hope that this is enough time for all of us to get up to speed on VB.Net to handle the VB6 overflow at that time.
I’ve got a lot to learn. My ongoing thanks to Dan and others here to help me keep my mind from wandering since I too am a hobby programmer for the most part, only really specializing in G-code, CAD and then Cad/Cam software to write literal “machine code.” Keep up the good work all of you. Ben
Ben …
Let me save you the trouble of checking EWeek. From Microsoft:
“Current and future developer tool products are now eligible for 5 years of Mainstream support, and 5 years of Extended support.”
“Visual Basic 6.0 IDE or Visual Studio 6.0 … Those products will move out of extended support in April 8, 2008″
The Vista OS will support the VB 6 runtime for a good long time to come (about 9 years, if we can trust the statements above) but Microsoft is dropping VB 6 as a development environment like a hot rock. Next April, the only response you will get from Microsoft about VB 6 syntax is “What? No speaka de language.”
poop ?
And duck poop at that!