Article View: comp.lang.misc
Article #4391Re: GOTO controversy
From: James Giles
Date: Mon, 11 Mar 1996 06:01
Date: Mon, 11 Mar 1996 06:01
140 lines
8514 bytes
8514 bytes
In 1968, Edsger Dijkstra wrote a letter to the _Communications_
_of_the_ACM_ titled "Go To Statement Considered Harmful". This
paper has since been widely reprinted. In 1974, Donald Knuth
wrote a paper for _Computing_Surveys_ titled "Structured
Programming with GOTO Statements". This paper has also been
widely reprinted. These were not the first nor the only papers
written on this subject, but to my mind, they should have been
the last needed. Anyone who argues this issue should first
be required to prove he (or she) has read both these papers.
Anyone who hasn't read these papers should be ignored out
of hand.
That being said, I'll go ahead and add my $0.02 to the mix.
I actually use GOTOs all the time. Except for the "hello world"
program, my programs tend to have thousands of GOTO's. For example,
an IF without a ELSE clause has one conditional GOTO, with an ELSE
there's both a conditional and an unconditional branch. A WHILE
loop has both conditional and unconditional branches too.
Now this is both trivially obvious and rather silly. But it still
raises the question of why CASE, IF(ELSE), WHILE(FOR, etc.), and
procedure calls are the only branches anointed as "structured".
It wasn't always so. Though these were the constructs mentioned in
Dijkstra's letter on the subject, there was no suggestion that these
were the *ONLY* appropriate constructs.
It is instructive to read Dijkstra's "Notes on Structured Programming"
in the book "Structured Programming" (Dijkstra, Dahl, Hoare, 1972).
Appropriate control constructs (according to Dijkstra) are those which
are simple enough and well understood enough to reason about clearly
and which help to break down the code into smaller independently
understandable chunks. So, even from a Dijkstra-conforming perspective,
if a particular form of branch is easy to reason about and simplifies
(or, at least doesn't complicate) the code, there is no reason not to
use it. That's how EXIT and CYCLE ('break' and 'continue' for you C
programmers) got accepted as (reasonably) "structured".
I have papers from the 60's and 70's recommending the following
instead of GOTO's (I use a pseudo language deliberately unlike
any particular language for examples - this avoids the inevitable
irrelevant wars):
while (cond1) next: while(cond1)
...some stuff... ...some stuff...
if (not cond2) goto next if (cond2)
...more stuff... ...more stuff...
end if end while
end while
Now the CYCLE statement would replace the GOTO these days, but is the
left version really easier to reason about? I don't think so. Is it
better modularization? I don't think so. And it's slower unless the
compiler is reasonably clever (to recognize an implicit branch to the
end of the loop is the same as one back to the beginning). Some real
purists may still prefer the left version - matter of taste in my opinion.
The corresponding example for the EXIT construct is much worse:
done = false
while (cond1 and not done) while(cond1)
...some stuff... ...some stuff...
done=cond2 goto out if (cond2)
if (not done) ...more stuff...
...more stuff... end while
endif out: ...
end while
The left version was actually *recommended* by the "structured
programming" zealots a while back (and perhaps by some of the real
die-hard cases even now). The EXIT statement encapsulates this
kind of GOTO, but even without it I find the left version much less
appealing than the right - the left version is *less* understandable,
it's not at all more modular, and it's obviously slower (even a very
aggressively smart compiler probably won't do as well - and such a
compiler takes longer to run itself!). Depending on the nature of
the conditions and/or the computation being performed there may be
a way of writing a structured code which isn't as bad as the left
version - but in the general case I think this is a good as purists
could manage.
I often think that auxiliary condition flags are much worse than
GOTOs in that instead of merely bypassing the intervening code, they
skim along underneath occasionally intruding in the form of yet
another redundant test of the flag. It is often claimed that one
of the problems with labeled statements is that you can't tell
how many branches target it or where those are. Well, tests of
auxiliary flags have the same problem - you can't tell where
it was set or how many different places might have manipulated
it. Branches do, however, have the property that a GOTO always
lands at a unique local label whereas auxiliary flags might be
referenced time and again throughout the code. In general, the
effect of such flags on the program's control flow can be more
complex than the effect of GOTOs.
Well so far all the "acceptable" branches have been amenable to
concealment under some name other than GOTO (even the original set
like WHILE and IF). Is that it? Is merely changing the name
sufficient to make GOTO acceptable? No, but it helps. It helps
because when you see just a GOTO in the middle of a code you must
look up the associated label and discover for yourself the properties
of the thing. They may or may not be conducive to easier understanding
or better modularization. However when you see one of these named
aliases for a particular type of GOTO, you have instantly a good idea
what its properties are. The purpose of the new name is not to conceal
that branches are present, but to more explicitly pin down the properties
of those branches.
What about the other way around? Are the only acceptable branches
those for which restrictive aliases are already common? That would
imply that the control constructs we already have were a complete
set. Well they are in a Turing-equivalency sense, but not necessarily
in the sense of being more easily understood, more modular, or both
(not to mention more efficient). I'm not arrogant enough to claim
that I understand all useful types of control structures and that
GOTO should be left out of all languages so that people can't try
to invent new ones anymore. Indeed, some of the uses of GOTO which
I personally find easy to understand and which I personally believe
tend to shorten and clarify the code are irritatingly illegal in
many of the programming languages I use (fortunately the need
for them is rare). Actually, if I had Zahn's situation indicators
(as described in Knuth's paper referenced above) I would probably
never need GOTOs again - but I don't have them.
Well, there's a lot more to talk about GOTOs (like exception handling!),
but this is enough for one article. The bottom line is that automatic
rejection of GOTOs for religious reasons loses sight of the real issues
which led to the controversy and often can lead to unfair disregard for
techniques which are perfectly sound. New kinds of GOTOs slowly reach
into the "structured" pantheon, but only very slowly (and perhaps correctly
so). Complete elimination of GOTOs from available languages would stop
this useful evolution entirely. In any case, people should not be so quick
to condemn *all* GOTOs out of hand. As Dijkstra himself pointed out:
Please don't fall into the trap of believing that I am terribly
dogmatical about it. I have a feeling that others are making a
religion out of it, as if the conceptual problems of programming
could be solved by a single trick, by a simple form of coding
discipline!
- E.W. Dijkstra
Technical Details
Message-ID:
<4i0fj8$sd3@tierra.santafe.edu>Path:
arc1-ca.pugleaf.net!internet.roadrunner.com!richrcarReferences:
<rcshlds.1.000A6705@mailserv.mta.ca> <4grt4e$8fg@goanna.cs.rmit.EDU.AU> <4hl8mt$4po@newshost.cyberramp.net> <4hlg11$dd7@news1.mnsinc.com> <4hpits$1p1v@b.stat.purdue.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!internet.roadrunner.com!richrcar From: richrcar@internet.roadrunner.com (James Giles) Newsgroups: comp.lang.misc,comp.lang.c,comp.lang.pl1 Subject: Re: GOTO controversy Followup-To: comp.lang.misc,comp.lang.c,comp.lang.pl1 Date: 11 Mar 1996 06:01:12 GMT Organization: The Santa Fe Institute Message-ID: <4i0fj8$sd3@tierra.santafe.edu> References: <rcshlds.1.000A6705@mailserv.mta.ca> <4grt4e$8fg@goanna.cs.rmit.EDU.AU> <4hl8mt$4po@newshost.cyberramp.net> <4hlg11$dd7@news1.mnsinc.com> <4hpits$1p1v@b.stat.purdue.edu> NNTP-Posting-Host: internet.roadrunner.com X-Newsreader: TIN [version 1.2 PL2]