Wordyard

Hand-forged posts since 2002

Scott Rosenberg

  • About
  • Greatest hits

Archives

Wordyard / Code Reads / Code Reads #2: Dijkstra’s “Go To Statement Considered Harmful”

Code Reads #2: Dijkstra’s “Go To Statement Considered Harmful”

October 10, 2006 by Scott Rosenberg 45 Comments

Code ReadsThis is the second edition of Code Reads, a weekly discussion of some of the central essays, documents and texts in the history of software. You can go straight to the comments and post something if you like. Here’s the full Code Reads archive.

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.

Filed Under: Code Reads, Software

Comments

  1. Scott Rosenberg

    October 10, 2006 at 7:28 pm

    “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…

  2. Sean O'Donnell

    October 10, 2006 at 9:15 pm

    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.

  3. Kevin Marks

    October 10, 2006 at 10:28 pm

    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.

  4. Amos Anan

    October 11, 2006 at 4:05 am

    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

  5. Joel Neely

    October 11, 2006 at 6:23 am

    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.

  6. Joel Neely

    October 11, 2006 at 6:30 am

    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!

  7. Julian Morrison

    October 11, 2006 at 7:27 am

    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”.

  8. Ian Rae

    October 11, 2006 at 8:18 am

    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?

  9. Dave Cattarin

    October 11, 2006 at 8:22 am

    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.

  10. Dave Cattarin

    October 11, 2006 at 8:26 am

    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.

  11. Ian Rae

    October 11, 2006 at 9:17 am

    “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.

  12. Dave Cattarin

    October 11, 2006 at 9:50 am

    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.

  13. Ian Rae

    October 11, 2006 at 10:02 am

    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.

  14. Dave Cattarin

    October 11, 2006 at 10:16 am

    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.

  15. Scott Rosenberg

    October 11, 2006 at 10:25 am

    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?”

  16. Brooks Moses

    October 11, 2006 at 10:57 am

    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).”

  17. Nestor

    October 11, 2006 at 12:19 pm

    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.

  18. Dave Cattarin

    October 11, 2006 at 12:19 pm

    “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.

  19. Brooks Moses

    October 11, 2006 at 2:37 pm

    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.

  20. Joel Neely

    October 12, 2006 at 4:47 am

    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.

  21. Joel Neely

    October 12, 2006 at 5:12 am

    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.)

  22. jw

    October 12, 2006 at 1:06 pm

    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 .

  23. Dave Cattarin

    October 12, 2006 at 1:34 pm

    Technically, Smith is an assembly language not machine language.

  24. Tommy McGuire

    October 12, 2006 at 2:53 pm

    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.

  25. Cleo Saulnier

    October 12, 2006 at 2:57 pm

    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.

  26. Tommy McGuire

    October 12, 2006 at 2:58 pm

    Scott, you’re apparently not the only one who likes to lecture.

  27. Scott Rosenberg

    October 12, 2006 at 7:54 pm

    Good, I’m glad for the company :-)

  28. Brian Slesinsky

    October 13, 2006 at 12:49 am

    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.

  29. r. clayton

    October 13, 2006 at 7:12 am

    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.

  30. Dave Cattarin

    October 13, 2006 at 7:56 am

    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.

  31. r. clayton

    October 13, 2006 at 5:24 pm

    Some things can’t be cleanly expressed without it, like coroutines or tail calls.

    All control statements are based on the goto statement whether it be conditionals, loops, breaks, continues, return or function calls.

    Both these comments overstate the case, I think. See Lambda: the Ultimate GOTO for an alternate view.

  32. Dave Cattarin

    October 13, 2006 at 6:18 pm

    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.

  33. Cleo Saulnier

    October 13, 2006 at 6:35 pm

    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?

  34. r. clayton

    October 13, 2006 at 7:46 pm

    How is this an alternate view? Sounds exactly like what I said.

    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.

  35. Curt Sampson

    October 16, 2006 at 10:13 pm

    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.

  36. Curt Sampson

    October 18, 2006 at 9:56 pm

    Actually, a paragraph near the end of Guy Steele’s
    Lambda: The Ultimate GOTO
    bears repeating here:

    This is the essential frustration we have experienced with GOTO. We discovered that GOTO was often being used even in situations where more appropriate and expressive constructs were available, and that it was being used for all sorts of purposes we hadn’t anticipated, and so we sought to eliminate unwanted concepts and programming styles by banning a construct. This is just as fruitless as eliminating iteration by banning DO-loops would be (people would just use GOTO or procedure calls), or eliminating recursion by banning procedure calls (people would, and do, simulate it by using an array as a stack). We need to get a better grasp on organizational concepts and their relationship to the individual constructs which make up our languages.

  37. Boris

    October 19, 2006 at 1:01 am

    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? :)

  38. Dave Cattarin

    October 19, 2006 at 7:29 am

    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.

  39. shaft oj

    July 9, 2007 at 11:41 am

    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

  40. shaft oj

    July 9, 2007 at 12:22 pm

    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

  41. Lori Rocha

    January 10, 2009 at 9:15 am

    hi
    gllbh7urwtdpg2ap
    good luck

Trackbacks

  1. Code Read 2 - Dijkstra on Goto » Skillful Software says:
    May 28, 2007 at 5:49 am

    […] arguing that the “goto” statement was bad for programmers and the programs they wrote. Week 2 of Code Reads covers this […]

  2. TDD Considered Harmful? - Jacob Proffitt says:
    February 22, 2008 at 6:28 pm

    […] I’m going to catch it for that title. Okay, let me get this out up front: this post is a hypothesis that I consider probable. That’s why […]

  3. language considered harmful II « ZEITGEISTING     p a t t e r n  r e c o n n a i s s a n c e says:
    March 14, 2008 at 12:40 am

    […] i found: – a small entry in wikipedia about the “considered harmful”-slogan, and – a blog-entry about this article (by a writer called Scott Rosenberg, who sais: “The content of […]

  4. Jarrett House North » Blog Archive » Around the ’sphere: Thank U says:
    April 29, 2008 at 9:58 am

    […] to Scott Rosenberg for a fascinating series on key written works that have influenced programming culture. I had never heard of Edsger Dijkstra’s “Humble Programmer” lecture but am […]

Leave a Reply Cancel reply

Your email address will not be published.