The title of Edsger Dijkstra’s 1968 “Go To Statement Considered Harmful” is among the best-known phrases in the history of programming. Interestingly, the phrasing of the title — which has become so regular a cliche in the field it inspired Eric Meyer to compose the waggish “‘Considered Harmful’ Essays Considered Harmful” — was not Dijkstra’s work at all. As Dijkstra explained it:
Finally a short story for the record. In 1968, the Communications of the ACM published a text of mine under the title “The goto statement considered harmful,” which in later years would be most frequently referenced, regrettably, however, often by authors who had seen no more of it than its title, which became a cornerstone of my fame by becoming a template: we would see all sorts of articles under the title “X considered harmful” for almost any X, including one titled “Dijkstra considered harmful.” But what had happened? I had submitted a paper under the title “A case against the goto statement”, which, in order to speed up its publication, the editor had changed into a “letter to the Editor”, and in the process he had given it a new title of his own invention! The editor was Niklaus Wirth.
How did Wirth come up with the odd phrase? My hunch is: some combination of English-as-a-second-language (though, since Wirth got his PhD here at Berkeley, that may be completely wrong) combined with the essential trait of radical concision drummed into the heads of programmers of that era. Fewer words! Fewer characters! Less space in memory!
The content of Dijkstra’s brief essay itself is far less widely known than its title. David Tribble, the author of an extensive annotation of the original essay, calls it “probably the least read document in all of programming lore” — hyperbole, but telling.
As Tribble and others have pointed out, Dijkstra didn’t advocate the total elimination of “go to,” but he did aim to radically curtail it: “The go to statement as it stands is just too primitive; it is too much an invitation to make a mess of one’s program.”
Dijsktra’s essay was an important milestone in the structured programming movement of its era. His argument is straightforward enough: “Go to” is problematic because, in jumping arbitrarily from one spot in a process to another, it fails to maintain context (or “state awareness”) — and that invites messes.
From what I can tell, the specifics of this debate have been largely left behind by the march of programming-language progress. Nonetheless I found plenty to chew on in Dijkstra’s brief essay, particular his assertion that the programmer’s “true subject matter” is creating the “process taking place under control of his program,” with the program and its code serving simply a means to that end.
I wonder what practicing programmers reading these arguments today make of them. Are there analogies in today’s languages to Dijkstra’s “invitation to make a mess”? Higher-level-abstraction versions of the “Go To” statement that we have yet to eliminate? Should “Go To Statement Considered Harmful” be on the software-document reading list at all — or should we let it age peacefully into its cliche-dom?
Post Revisions:
There are no revisions for this post.
“Go To Considered Harmful” ushered in a considerable debate over the shape and nature of structured programming, which produced at least two key documents — Dijkstra’s 1969 “Notes on Structured Programming” and Donald Knuth’s 1974 “Structured Programming with go to Statements” (thanks to Jim Jinkins for the suggestion). If there’s interest we could set those up as the next two “Code Reads.” Or take a “Go To” leap to something entirely different…
I think this statement was particalarly insightful
“our intellectual powers are rather geared to master static relations and that our powers to visualize processes evolving in time are relatively poorly developed”
It could be argued that the ability to visualize processes evolving in time is one of the core skills of a good developer, also it fits with the level of fear most developers seem to approach multithreaded programming
Also while the specifics of the paper may have been rendered irrelevant by the march of time, the overall theme is very much alive. Java for example seems to be influenced by the school of ‘Multiple Inheritence considered harmful’ and ‘Operator overloading considered harmful’. Most languages seem to think lisp style macros are too dangerous. Even static vs dynamic typing could be seen as a ‘considered harmful’ arguement.
Thanks for kicking off such a great series, Im looking forward to the next installment.
Goto is legitimate in C code for handling disposal of heap-allocated objects in a failure state – see the examples in:
http://homepage.mac.com/kevinmarks/personality.html
This avoid excessive if-nesting with allocations. A within-function exception could be used for this in C++ (though raising exceptions on error without a containing catch clause can leak all kinds of things).
A dynamic language with exceptions properly integrated, such as Python, does not suffer from these kinds of leaks.
I think you’ve left more complexity in the issue than is needed.
/* …………………………………………..
His argument is straightforward enough: “Go to” is problematic because, in jumping arbitrarily from one spot in a process to another, it fails to maintain context (or “state awareness”) — and that invites messes.
………………………………………….. */ :P
This almost sounds like gotos that violate stack integrity, which I don’t think is what’s meant. My old ‘Compilers’ teacher put it much more simply using what was the common phrasing of the day. “The problem with gotos isn’t the ‘goto,’ it’s the ‘wherefrom.'” “State awareness” is “how the f*ck did I get here?” The common description of goto heavy code was “spaghetti code,” with the “spaghetti” invisible. Shoots and ladders without visible shoots or ladders.
I haven’t been a programmer in years and even then my knowledge of the state of the art was limited, but “bleeding edge” often seemed an apt description of the situations I’d sometimes find myself in. Message loop based programs were archetypical examples of the “wherefrom” problem. I’d look at code and ask myself “How did I get here?” and being “here,” what’s the cause of the problem I’m in since I’m not sure where I came from. “State awareness.” The goto may have been replaced but it’s been replaced with a fundamental that in some ways seems much worse.
When I first started to learn C++ from C the concept of being able to define or redefine fundamental language statements seemed terrific. C’s lack of simple handling of strings could be built in (plugged in?) and customized. I was short sighted even as I looked at the various texts that used different approaches to building string handling and other operations into assignment statements.
The problem quickly became apparent when using some more established “library.” Something which had come to be called “classes.” Microsoft must have loved it though. If you used “Microsoft Foundation Classes” to write your programs then you were immediately on a tether that Microsoft could pull at any time. (A new kind of spaghetti?) Each programming house that you went to had its own class library – its own version of C++. Talk about “state awareness.” It was the nightmare of Brian Kernighan’s beloved “little languages.” There was no real C++. It was as if you traveled from a cane field in Jamaica to a bayou in Louisiana and then on to Chicoutimi. The languages may somehow have seemed vaguely familiar but it would take time and much effort (redundant at that) before any efficiency in the milieu would be achieved.
“What language do you dream in?” became “What language is your nightmare in?” State awareness indeed. :P
I’m not sure about “least read”, but I firmly believe that “least completely understood” is an appropriate description of Dijkstra’s paper (and quite a bit of his work). I believe that reading of Dijkstra’s longer works “Structured Programming” [EWD268], “Notes on Structured Programming”, and “A Discipline of Programming” make it clear that the infamous “goto” was a symptom and not a root cause.
There are arbitrarily many ways in which one could take the materials from a local building-supply outlet and begin assembling a building. If we watch a professional team design and build a typical residence, we see that they restrict themselves to a TINY portion of the total ways their materials could be used. For example, it would be hard NOT to find use of the typical 2×4-stud-wall, even though there are many more ways to put pieces of wood together (including forms more interesting than a diagonally-braced rectangle!)
It’s not a lack of imagination at work; the architects and carpenters use those familiar patterns precisely because those patterns (and their properties) are well understood. They don’t have to worry about whether a load-bearing wall is actually strong enough to bear the load. Home ownership would be much more expensive (and risky!) if the architects and builders were constantly having to use complex engineering calculations, or (worse) trial and error at the home-owner’s expense, to determine whether the house would remain standing.
“Structure” is about the relationships between a whole and its constituent parts. Dijkstra argued eloquently and forcefully throughout his writing and teaching career that one can only avoid fatal, unmanaged complexity by first thinking carefully about those relationships, and then by expressing one’s thoughts in a notation that remains as close to the shape of the thoughts as possible.
In teaching I have referred to the opposite of Dijkstra’s approach as the “James Joyce school of programming” in which the programmer begins scribbling ideas into code in stream-of-consciousness fashion, jumping around within the growing mass of code when recognizing “I’ve already done something like this somewhere in here.” That way lies madness (or at least lots of bugs! ;-)
Unfortunately, the snake-oil salesmen grabbed the term “structured programming” and marketed it into a meaningless buzz-phrase, a software-tech equivalent of fad diets and instant weight loss pills. I’m fascinated that your first two readings are the product of brilliant thinkers who argued that there are no effortless solutions to the problems of the unmanaged complexity that we so easily–and frequently–create. Brooks’ “No Silver Bullets” and Dijkstra’s “The Humble Programmer” [EWD340] are full of lessons which the rush to “quick wins” ignores. Dijkstra closed “The Humble Programmer” with profound advice:
“We shall do a much better programming job, provided that we approach the task with a full appreciation of its tremendous difficulty, provided that we stick to modest and elegant programming languages, provided that we respect the intrinsic limitations of the human mind and approach the task as Very Humble Programmers.”
I heartily recommend the “EWD series” at http://www.cs.utexas.edu/users/EWD/ to anyone who wants to see a wealth of ideas which were ahead of their time, many of which are still unrealized.
I failed to mention that “Notes on Structured Programming” is EWD249, for the convenience of anyone who’d like to read it. Sorry for the omission!
The “…considered harmful” phrasing was inserted by an editor and wasn’t the original title.
Goto may complicate proof but it makes a programming language strictly more powerful. Some things can’t be cleanly expressed without it, like coroutines or tail calls. C left out “goto function(parameters);” and high-level languages using C as a compiler target have had to jump unnecessary hoops ever since. Google “Cheney on the MTA”.
By the early Eighties, EWD’s dictum was widely taught. Those of us learning to program at that time never used GOTOs and didn’t miss them.
Kudos to Amos’ comment about new types of ‘spagetti’ cropping up. Polymorphism can be a pasta nightmare. What method exactly does foo->Bar() call?? And isn’t the fragile base class problem just another case of “state awareness” problems?
As Joel said, “[Dijkstra’s writings] make it clear that the infamous “goto” was a symptom and not a root cause.” Definitely. Dijkstra’s tirade was primarily aimed at what we now call spaghetti code.
As already noted, there are places where goto can be useful. Dijkstra didn’t have a problem with that. What he wanted was people to design their programs and not use goto as a means to slap things together. This is why he talks about “structured” programming. In the late 70s and 80s, this was a popular form of design, though it was eventually suplanted by OO.
Kudos to Amos’ comment about new types of ‘spagetti’ cropping up. Polymorphism can be a pasta nightmare.
True, but any language feature can be abused. Polymorphism, when used correctly, can make code much cleaner and easier to understand. Again, the issue is design.
“True, but any language feature can be abused.”
Looking carefully at EWD’s paper, it’s not a call for good taste and restraint. It doesn’t contain the words “spagetti” or “structured programming”. It’s an explanation of why a specific programming construct, namely GOTO, is bad and should be “abolished from all ‘higher level’ programming languages”.
Polymorphism seems like a first stab at OO, and has recently been largely replaced by interfaces and dependency injection. The choice in Java of every function being virtual by default may come as well to be seen as harmful.
True, EWD does not say “spaghetti” nor “structured programming” in that paper.
Dijkstra sometimes liked to overstate his case to make a point. Remember his quote about programmers that learned BASIC first would essentially be worthless?
IMO, EWD called for the elmination of goto to avoid the misuses, but he has two qualifications in his article. The first, as you partially quoted was: “should be abolished from all “higher level” programming languages (i.e. everything except, perhaps, plain machine code).” Later in the article he says, with my emphasis: “The go to statement as it stands is just too primitive; it is too much an invitation to make a mess of one’s program. One can regard and appreciate the clauses considered as bridling its use.” Bridling implies that goto could be used but with severe restrictions.
In any case, he goes on to say that “whatever clauses are suggested (e.g. abortion clauses) they should satisfy the requirement that a programmer independent coordinate system can be maintained to describe the process in a helpful and manageable way.” To me, that says he wants to see better design.
When you say that “Polymorphism seems like a first stab at OO, and has recently been largely replaced by interfaces and dependency injection.” It sounds like you are confusing inheritance and polymorphism. They are related, but are not the same things.
Yes, EWD does appear to like overstating things a bit; his sentence on abolishing GOTO, ends with “(i.e. everything except, perhaps, plain machine code)”. Machine code with a BRANCH instruction! I find the “perhaps” outrageous, or more likely facetious.
Language designers face a continium of choices; not just whether a feature is in or out. EWD hints at this with his “as it stands”, as you say. C# allows polymorphism but requires both the base class writer to say “virtual” and the derived class writer to say “overridden”. A double handshake to ensure everyone knows what’s up.
I hope I’m not confusing inheritance with polymorphism. The former without the latter is just fancy code re-use. Any real OO system requires that derived classes can be used in place of the base class; an Ellipse IS-A Circle (or vice-versa!). This requires dynamic dispatch.
Reading EWD is always fun. :)
So polymorphism… I guess I should say that it is realized in many ways (inheritance, generics, interfaces, etc). So, your statement that polymorphism was “largely replaced by interfaces and dependency injection” didn’t seem quite right to me; it sounds like polymorphism was replaced by polymorphism, if you see what I mean. I hope that makes my thoughts a little clearer.
Amos, I really like your explanation — that the problem isn’t so much the “goto” as the “wherefrom.” I can just see the program waking up and singing the old Talking Heads lyric:
“And you may ask yourself: how did I get here?”
But if the “wherefrom” was the problem, then Intercal’s “COME FROM” statement wouldn’t actually be a joke. There’s a parallel “And where am I going to?” question.
This is arguably why the idea of subroutines is so powerful (and why global variables undermine it), in that it abstracts away this question. When we start a procedure, all of the information that we might care about as far as where we came from is abstracted away into the procedure arguments. Then, when we return, the same abstraction happens in reverse; ideally, with a function, it’s all abstracted away into the function result, and all we need to know is “We came from something that calculated f(x).”
Let me illustrate one problem with goto:
Line
10 step 1
20 step 2
30 conditional branch A to 10
40 conditional branch B to 20
50 T
1>2>A>1>2>A>1>2>A
______>B>2>A>1>2>A>1>2>A
_____________>B>2>A>1>2>A
____________________>B>2>A>1>2>A
______________________>T
Pattern: 2-1,2
B
|
v
A->1
|->2
.…^
B–|
Structured:
5 while B
10 step 1
15 while A
20 step 2
30 repeat A
40 repeat B
50 T
1>2>A>2>A>2>A
______>B>1>A>2>A>2>A
____________>B>1>A>2>A
_______________>T
Pattern: 1-2
B->A->2
|
v
1
The second example has the same number of branches, same number of steps but is much simpler to follow. Only local steps affect branches that are at the center. Condition on line 30 has to terminate based on a change in state of step 2 (or we get an infinite loop or a loop that executes only once).
Of course many of you already realized this. For me then the discussion boils down to “trees are easier to understand visualize and follow than graphs”. Structured loops can be understood in a hierarchy because they have to be nested correctly. Gotos do not have that requirement. The same can be said about multiple inheritance. Unfortunately reality is not always hierarchical but sometimes really more like a graph. In those cases trying to map reality to a tree does not help much to make things easier. Like Einstein said: “make everything as simple as possible, but not simpler”, trees if possible graphs if necessary.
“And you may ask yourself: how did I get here?”
Well, a number of languages, such as Smalltalk and Java, have the stack available as an object. So, in theory, it is possible to answer that question. More often than not, however, when you need to ask “how I got here” is when the stack won’t tell you what you really need to know.
You can look at EWD’s article as an education campaign: he’s trying to proactively “fix” certain types of bugs by getting people to stop using goto. In a way, that’s what a lot of the “considered harmful” articles try to do: education.
Restricting “bad/harmful” language features can reduce bugs to a certain extent, but from what I’ve seen, the effective goal of most language designs, as well as support tools, is to make it easier to build programs. Debugging support is left as a side-issue.
Improving debugging is difficult, but we certainly need better tools than the ice-age ones we have now.
Nestor: I don’t think it’s really debateable that, with GOTO, one can write really incomprehensible code. I don’t think that proves that GOTO is bad; merely that like any powerful tool it can be used to make a big mess.
A slightly more interesting question is whether, with GOTO, it’s more likely that people will make big messes. One can’t really prove that by quoting code — that just shows the boundaries of the possible, and we know that both messes and clear code are possible regardless of the tools one uses. Dijkstra’s article makes the case that the answer is, indeed, that it’s more likely — not only is GOTO powerful, but it’s also designed in such a way that it’s easier to do things “incorrectly” than “correctly”. But I think this question, too, has long been answered — Dijkstra’s right in the general case, but there are specific cases where using GOTO is the right answer.
I think that the really interesting question, though, is how this extends to current-day practices. Dijkstra was considering essentially just simple FOR loops, IF blocks, and GOTO statements, which is quite a limited selection compared to what today’s languages offer. However, he also presents a means of evaluating whether or not a type of control statement is “good” or “bad”, and I think the merits of that evaluation are the really interesting question.
I think there are certainly analogues to GOTO in the sense of “invitations to make a mess”; case statements with fall-through are an obvious (and trivial) example.
Personally, I’m going to make what I hope is a controversial statement: “malloc” and “free” (and any similar features that allow memory leaks, such as C++’s “new” and “delete”) are an equivalent invitation to make a mess. In nearly all cases, there are better alternatives (although in some cases they don’t exist in mainstream languages yet), and languages that don’t provide them should be avoided for high-level programming. Thoughts of “who’s responsible for freeing this memory?” are distractions from the bigger questions.
I also think that garbage collection is often a patch on the problem rather than a true cure. It fixes the symptoms.
Brooks: Your comments about malloc and free are on target, and are precisely another example of what I believe was Dijkstra’s central point. FWIW, D.C. Ince had a piece in ACM SIGPLAN Notices, January 1992, entitled “Arrays and Pointers Considered Harmful” which made essentially the same point.
Julian: I’m sorry, but I must emphatically disagree. The presence of an unconstrained jump instruction does not make a language “strictly more powerful” in any formal sense. That was exactly the point of the Bohm and Jacopini paper which Dijkstra cited.
It is certainly possible to write goto-free code badly, just as it is possible to misuse any other language concept. However, the fact that I can present an awkward piece of code in style A alongside a simpler-looking piece of code in style B does mean that I have proven that style B is inherently superior.
One used to hear arguments of the form “Yes, but the compiler turns all of those “if…then”s and “while”s into “goto”s at the machine level. And that’s really a key issue, IMHO, in two respects:
1) It really isn’t true. At the “machine level”, all that’s happening is that a CPU register (e.g. the “instruction pointer”, or some such name) is being changed in a different way than simply adding one. Nothing “goes” anywhere in a CPU except electrons.
Why would I be so incredibly pedantic? To make the second point more vivid.
2) It makes us think about the wrong details. ALL of our descriptions of what goes on in progamming are really metaphors. A crucial part of the maturing of programming and computing science is that we’ve started making metaphors that are about what we humans are doing with the computer, rather than about how the hardware implements its business. After all, if I’m using a spreadsheet to balance my checkbook, I don’t worry about the individual bits in the floating-point numbers! (And I certainly don’t worry about the electrons! ;-)
Somebody needed to worry about the bits in the floating-point numbers while the CPU was being designed, and again while the compiler and run-time libraries were being designed. After that, we should be able to take them as done and move on to higher things. (Yes, a few people are doing high-precision, high-performance number-crunching, so they are entitled to worry about it a little bit, but not the rest of us.)
Yes, EWD does appear to like overstating things a bit; his sentence on abolishing GOTO, ends with “(i.e. everything except, perhaps, plain machine code)”. Machine code with a BRANCH instruction! I find the “perhaps” outrageous, or more likely facetious.
It’s not an overstatement. There is at least one machine language without branches or jumps: Smith .
Technically, Smith is an assembly language not machine language.
My dissertation advisor has a really snazzy formal notation for describing network protocols. One of the elements of this notation is essentially a global conditional statement. When he introduces this particular element in a class, he tends to say something to the effect of, “and every time you use this, you have to give me a thousand dollars.” He does that because, althogh the element is a key part of the notation and vital for reasoning about protocols, “unbridled” use of it is far too easy—everytime you do use it, you need to ask, “How am I actually going to do this?”
Goto has the opposite problem: Using it can make reasoning about a program very difficult. If you are not careful, it essentially limits you to reasoning dynamically—you have to pretend to be the computer. That, I think, is the point of Dijkstra’s “coordinates”. Without them, you essentially have to understand the entire program to reason about any of it. Many advances in programming that are now taken for granted, like structured programming and lexical scoping, are intended to allow static reasoning about programs, as text on the screen in front of you.
So, what do I mean be “careful”? There is a really lovely paper that for the life of me I cannot find. I think it is by Tony Hoare but possibly by Knuth. It presents a formalism of goto in terms of preconditions and postconditions, where the postcondition of a statement “goto L” is false and the precondition of the statement is the precondition of the code at L. If you can build that kind of argument about your use of goto, and ensure that all uses of “goto L” satisfy it, then you may well be all right. That is the thousand dollars that you have to give to Dijkstra’s ghost.
I had a somewhat different take on “Goto Considered Harmful”. I thought it showed the difficulty in tracking state when the primary tool that controls the ordering of statements, known as the execution point, is used haphazardly. Today, this problem is more apparent with the use of threads where you have more than one execution point. It’s not just about who is doing what when. But about in what order are things being done. In either case, it’s about not corrupting state.
One of the worst frame of minds we can take is that goto’s should be abolished it completely. All control statements are based on the goto statement whether it be conditionals, loops, breaks, continues, return or function calls. I see a use for advanced breaks that can break multiple levels or break completely out of all nested loops in a function. Same thing for continue. Power loops are another example. Now what would we do if we cut out the goto before the break or continue statements came into existance? I remember using sentinel values and conditionals. Sometimes, the counter variable was set past its maximum and the rest of the loop had to be checked in order for it to be skipped over. The current control statements that we use today are restricted uses of the goto statement. Abolishing the foundation is as bad a scenario as you can have because it limits further innovations on control structures.
I took this notion of danger with control structures as something that underlies a more sinister problem with software construction. That maybe control statements aren’t the best way to track state. I’d rather outline the order that data should be transformed instead and not use any execution point at all which is a low level and unecessary construct anyways. Unfortunately, I seem to be in an extreme minority. I, for one, cannot adhere to the notion that seems to be prevalent which says that if the foundation is flawed, the rest doesn’t have to be. No, if goto’s are harmful, then all control structures are in the same boat. They may be *less* harmful, but they’re still dangerous.
Execution points are low level. Keep it in low level languages and OS’s. Higher level languages and software development tools shouldn’t deal with it at all.
Scott, you’re apparently not the only one who likes to lecture.
Good, I’m glad for the company :-)
In modern programming terms, Dijkstra’s argument is built on the importance of being able to use a stack trace to describe the current execution point of a program. In a sequential program with no loops, you can think of each possible execution state as being uniquely identified by a stack trace. That is, each possible stack trace will occur at most once when the program executes.
If you add loops, you also need to keep track of how many times each loop has repeated.
We use stack traces all the time for logging, debugging, and profiling. These days there is often a list of stack traces, one for each thread. But there seems not to be any pressing need to count how many times a loop executed as Dijkstra suggested. Having a stack trace seems to be a good enough description of “the point at which the error occurred” most of the time.
I wonder whether that’s because we don’t use goto much any more? Or is it because even when there is a goto statement, it only jumps within a function; each function still has a single entry point.
Are there analogies in today’s languages to Dijkstra’s “invitation to make a mess”?
There is: object-oriented design based on state and code inheritance (what I like to think of as the tragedy of the 90s). I came to this conclusion by considering techniques for oo metrics and testing: most of the ones I’m familiar with are some combination of difficult, clumsy, ineffectual and costly. Because state and code can be smeared along the inheritance hierarchy, there’s no local thinking; unless you work to make it otherwise (that is, avoid the tragedy of the 90s), it’s all effectively global.
Because state and code can be smeared along the inheritance hierarchy, there’s no local thinking;
Ah, but the same can be said of any poorly designed piece of code; it is not an inherent weakness of OO. Not that OO is perfect. There is a lot of bad code out there, but that is more a function of poor programmers than anything else.
In any case, OO was a reaction to try and improve structured programming. Possibly, AOP will be an improvement on OO. We are constantly trying to evolve our tools to make problem solving simpler.
Both these comments overstate the case, I think. See Lambda: the Ultimate GOTO for an alternate view.
I think one of the notes in that article summarizes states the case very well:
“This brings out a serious flaw in the present theory of structured programming; by assuming that all programs can conveniently be written using only certain structures, it implicitly assumes that the problems to be solved by these programs have solutions which can be decomposed using these structures.”
Actually, I think this applies to any form of programming/design and why ” is considered harmful” always needs to be taken with a grain of salt.
r. clayton: From the link you provide: “In all fairness, it should be pointed out that GOTO is a basic, universal primitive with which (in conjunction with a conditional) almost any other control construct can be synthesized if the language designer neglected to include it.”
How is this an alternate view? Sounds exactly like what I said.
However, that paper was bogus in its time, but would be somewhat correct today in a weird twist of irony where we have caches, branch prediction, multiple dispatch (until the correct branch can be determined, not sure the name of this), pipelining, etc… that can make the call almost as fast as a goto. Calls are still slower, but when it accounts for almost 0% of the total runtime, who really cares anymore?
It is: Steele is paraphrasing arguments such as yours (the first sentence of the paragraph you quote is “Some programmers fear that their expressive power or style will be cramped if GOTO is taken away from them.”). I interpreted your comment as an argument for the necessity of gotos, from which you could imply their virtue. I interpret the rest of Steele’s paper as reducing gotos from a necessity to a sufficiency, which blunts the force obliging us to accept gotos. This is the first alternative: we are compelled to have gotos because we need them vs. gotos aren’t the only game in town.
Reducing necessity with sufficiency leaves choice: which is better? I also interpret the rest of the paper as an argument for favoring procedure calls over gotos several reasons, including Dijkstra’s concern about the programmer’s ability to reason about the dynamic behavior of the result. This is the second alternative: procedure calls vs. gotos.
I disagree that, “the specifics of the paper may have been rendered irrelevant by the march of time.” The main point of the paper does not seem to be gotos themselves, but rather their effect on programmers’ ability to intuit what the state of a set of variables might be at any given point in a program’s execution. And indeed, intuiting this incorrectly is a major source of program errors.
“Structured programming” has helped greatly with this, but I think we have yet a long way to go. Purely functional languages are one attempt to take the next major step in improving this situation, and are possibly an even more radical step than that from gotos to structured programming.
I’d suggest having a look at Haskell for some ideas on where we might go from here. That language uses some interesting ways of making it easier to intuit state, mostly by getting rid of state. There is no way to change the value of a variable once it’s been assigned, for example: the first assignment sets the constant value for that entire scope.
Actually, a paragraph near the end of Guy Steele’s
Lambda: The Ultimate GOTO bears repeating here:
I’ve come to conclusion, that life is too complicated to consider anything harmful in computer languages. The complete freedom in choosing programming tools and paradigms is the answer. Goto… Multiple Inheritance… Pattern Matching… Garbage Collector… Deterministic memory release if all this could be combined in one language it woud be the ultimative language, could it? :)
Maybe, but that sounds too much like the fabled “silver bullet”.
Anyway, as much as we may dislike it, the choice of a language for a project tends to be more of a political/economic decision. So, we just have to make the best of the tools we have to do our jobs.
Hi Scott,
am a new beginner on Basic Programming and i have a problem solving a question on BASIC and the question goes like:
Determine the purpose of each of the following pieces of code and re-write them so that they do not use any GOTO statement.
A:
10 x=1
20 if x > 500 THEN GOTO 60
30 PRINT x ; SQR (x) ; x+500 ; SQR(x+500)
40 X = x+1
50 GOTO 20
60 END
B:
10 I = 0
20 if I > 10 THEN 60
30 PRINT I ;
40 I = I + 1
50 GOTO 20
60 I = 1
70 IF I > 10 THEN GOTO 170
80 PRINT I ;
90 J = 1
100 IF J > 10 THEN GOTO 140
110 PRINT I * J
120 J = J + 1
130 GOTO 100
140 PRINT
150 I = I + 1
160 GOTO 70
170 END
I will be glad if i could be able to get a solution to this problem via my email address.
Thanks
oj
Hi Scott,
am a new beginner on Basic Programming and i have a problem solving a question on BASIC and the question goes like:
Determine the purpose of each of the following pieces of code and re-write them so that they do not use any GOTO statement.
A:
10 x=1
20 if x > 500 THEN GOTO 60
30 PRINT x ; SQR (x) ; x+500 ; SQR(x+500)
40 X = x+1
50 GOTO 20
60 END
B:
10 I = 0
20 if I > 10 THEN 60
30 PRINT I ;
40 I = I + 1
50 GOTO 20
60 I = 1
70 IF I > 10 THEN GOTO 170
80 PRINT I ;
90 J = 1
100 IF J > 10 THEN GOTO 140
110 PRINT I * J
120 J = J + 1
130 GOTO 100
140 PRINT
150 I = I + 1
160 GOTO 70
170 END
I will be glad if i could be able to get a solution to this problem via my email address mib4life55@yahoo.com
Thanks
oj
hi
gllbh7urwtdpg2ap
good luck