Go To Statement Considered Harmful—— Dijkstra

Key Words and Phrases: go to statement, jump instruction, branch instruction, conditional clause, alternative clause, repetitive clause, program intelligibility, program sequencing


        For a number of years I have been familiar with the observation that the quality of programmers is a decreasing function of the density of goto statements in the programs they produce. More recently I discovered why the use of the go to statement has such disastrous effects, and 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). At that time I did not attach too much importance to this discovery; I now submit my considerations for publication because in very recent discussions in which the subject turned up, I have been urged to do so.

        多年以来我一直注意到程序员的水平和他们goto语句的使用密度成递减关系。直到前段时间我发现了为什么使用goto语句如此有害,并且我相信所有的“高级”编程语言都不应该再支持goto语句。当时我并没有认为这项发现有多重要,但在最近一次涉及该问题的讨论中,有人敦促我发表这些看法。


        My first remark is that, although the programmer's activity ends when he has constructed a correct program, the process taking place under control of his program is the true subject matter of his activity,for it is this process that has to accomplish the desired effect; it is this process that in its dynamic behavior has to satisfy the desired specifications. Yet, once the program has been made, the"making' of the corresponding process is delegated to the machine.

        我的第一个看法是,虽然程序员的工作在他们写出了正确的程序(program)后就结束了,但在此程序控制下的进程(process)才是真正重要的,因为是进程而不是程序来真正完成所需任务,是这种动态行为符合了我们期许的效果。一旦程序写完后,相应的进程就转交给了机器来做。


        My second remark is that our intellectual powers are rather geared to master static relations and that our powers to visualize processes evolving in time are relatively poorly developed. For that reason we should do (as wise programmers aware of our limitations) our utmost to shorten the conceptual gap between the static program and the dynamic process, to make the correspondence between the program(spread out in text space) and the process (spread out in time) as trivial as possible.

        我的第二个看法是,我们的大脑善于处理静态关系,而不善于想象随时间进行的动态执行流程。所以我们应该(聪明的程序员明白自己的局限性)尽力缩小静态程序和动态进程之间的概念差距,让文本里的程序(program)和时间轴上的进程(process)的对应尽量简单。

        Let us now consider how we can characterize the progress of a process.(You may think about this question in a very concrete manner: suppose that a process, considered as a time succession of actions, is stopped after an arbitrary action, what data do we have to fix in order that we can redo the process until the very same point?) If the program text is a pure concatenation of, say, assignment statements(for the purpose of this discussion regarded as the descriptions of single actions) it is sufficient to point in the program text to a point between two successive action descriptions. (In the absence of go to statements I can permit myself the syntactic ambiguity in the last three words of the previous sentence: if we parse them as"successive (action descriptions)" we mean successive in text space; if we parse as "(successive action) descriptions"we mean successive in time.) Let us call such a pointer to a suitable place in the text a "textual index."

        现在让我们考虑如何度量进程的进度(progress of a process),(你可以这样来想,一个进程,有一连串动作action,可能在任意一个动作时停止,为了之后可以从头开始重做到这步,我们如何标记这步?)如果程序(program)只是一连串的比如赋值语句(为方便讨论,用它来代指单个动作脚本),那么只要指到程序文本(program)中相邻动作脚本中间的一点就足够了。我们称指向文本中的这个指针为文本索引(textual index)。


        When we include conditional clauses (if B then A), alternative clauses (if B then A1 else A2), choice clauses as introduced by C. A. R. Hoare(case[i] of (A1, A2,···, An)),or conditional expressions as introduced by J. McCarthy (B1 -> E1, B2 -> E2, ···, Bn ->En), the fact remains that the progress of the process remains characterized by a single textual index.

        当我们引入条件语句(if B then A,二选一语句(if B then A1 else A2),C.A.R.Hoare引入的选择语句(case i of (A1, A2, ...,An)),以及J.McCarthy引入的条件表达式(B1->E1,B2->E2, ..., Bn->En),进程的进度依然可以用单个文本索引(textual index)来标识。


        As soon as we include in our language procedures we must admit that a single textual index is no longer sufficient. In the case that a textual index points to the interior of a procedure body the dynamic progress is only characterized when we also give to which call of the procedure we refer. With the inclusion of procedures we can characterize the progress of the process via a sequence of textual indices, the length of this sequence being equal to the dynamic depth of procedure calling.

        一旦我们引入过程(procedure),我们必须承认单个文本索引不够用了。当文本索引在一个过程中间时,必须加上谁在调用此过程的信息后,动态进程的进度才能标识。所以引入过程概念我们可以通过一序列的文本索引(sequence of textual indices)来标识进程进度,序列长度等于过程调用的动态深度。


        Let us now consider repetition clauses (like, while B repeat A or repeat A until B). Logically speaking, such clauses are now superfluous,because we can express repetition with the aid of recursive procedures. For reasons of realism I don't wish to exclude them: on the one hand, repetition clauses can be implemented quite comfortably with present day finite equipment; on the other hand, the reasoning pattern known as "induction" makes us well equipped to retain our intellectual grasp on the processes generated by repetition clauses. With the inclusion of the repetition clauses textual indices are no longer sufficient to describe the dynamic progress of the process. With each entry into a repetition clause,however, we can associate a so-called "dynamic index,"inexorably counting the ordinal number of the corresponding current repetition. As repetition clauses (just as procedure calls) may be applied nestedly, we find that now the progress of the process can always be uniquely characterized by a (mixed) sequence of textual and/or dynamic indices.

        现在让我们考虑循环语句,(比如,while B repeat A repeat A util B)。理论上说,这些语句都是多余的,因为我们可以用递归过程来表达循环。因为现实原因我不愿意去掉它们,一方面循环可被当今有限的机器很好的实现;另一方面称为“归纳”的推理模式让我们对循环语句的执行情况保持足够的理解力。引入循环后文本索引不再足够描述进程的动态进度。对循环的每个entry我们关联个当前循环的序列计数。称之为动态索引(dynamic index)。像过程调用一样循环也可能嵌套,现在进程进度可通过一序列的文本和动态索引(sequence of textual and/or dynamic indices)来唯一标识。


        The main point is that the values of these indices are outside programmer's control; they are generated (either by the write-up of his program or by the dynamic evolution of the process) whether he wishes or not. They provide independent coordinates in which to describe the progress of the process.

        这些索引的价值主要在于它们不在程序员的控制范围内;不管愿意与否,它们都可以被生成(或被程序记载或进程动态生成)。它们提供了独立的衡量坐标(independent coordinate)来描述进程进度。


        Why do we need such independent coordinates? The reason is - and this seems to be inherent to sequential processes - that we can interpret the value of a variable only with respect to the progress of the process. If we wish to count the number, n say, of people in an initially empty room, we can achieve this by increasing n by one whenever we see someone entering the room. In the in-between moment that we have observed someone entering the room but have not yet performed the subsequent increase of n, its value equals the number of people in the room minus one!

        为什么我们需要这样的独立坐标?原因在于-并且这似乎也是顺序进程所固有的-我们只有通过进程进度才能理解变量的值。如果我们希望对进入房间的人计数比如说n,我们可以每次看到有人进去后对n递增1。在看到人进去但还没得及对n1的中间时刻,n的值等于房间人数减1


        The unbridled use of the go to statement has an immediate consequence that it becomes terribly hard to find a meaningful set of coordinates in which to describe the process progress. Usually, people take into account as well the values of some well chosen variables, but this is out of the question because it is relative to the progress that the meaning of these values is to be understood! With the go to statement one can, of course, still describe the progress uniquely by a counter counting the number of actions performed since program start (viz. a kind of normalized clock). The difficulty is that such a coordinate,although unique, is utterly unhelpful. In such a coordinate system it becomes an extremely complicated affair to define all those points of progress where, say, n equals the number of persons in the room minus one!

        goto语句的滥用导致很难找到有意义的一组坐标来描述进程进度。通常人们会度量一组精心选择的变量,但这只有跟进程进度联系起来才有意义!使用goto语句,当然可以用程序开始后的动作执行数来精确的描述进度。问题在于这样的一个坐标虽然精确但完全无用的。在这样的坐标系统里要定义一个进程点,比如说n=房间里的人数-1,将变得异常困难。

        The goto 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. I do not claim that the clauses mentioned are exhaustive in the sense that they will satisfy all needs, but 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.

        goto语句太原始了,它诱使程序写的一团乱。我们可以使用上面引入的语句来控制goto的使用。我不是声称上面提到的语句会满足所有的需求,我想说的是不管引入什么语句(比如abort语句),它们都应该能让这个独立于程序员的坐标系统,方便有用可控的描述进程进度。


        It is hard to end this with a fair acknowledgment. Am I to judge by whommy thinking has been influenced? It is fairly obvious that I am not uninfluenced by Peter Landin and Christopher Strachey. Finally I should like to record (as I remember it quite distinctly) how Heinz Zemanek at the pre-ALGOL meeting in early 1959 in Copenhagen quite explicitly expressed his doubts whether the go to statement should be treated on equal syntactic footing with the assignment statement. To a modest extent I blame myself for not having then drawn the consequences of his remark

最后,很难做个公平的致谢。很明显我不会不受Peter LandinChristopher Strachey的影响。最后我想指出(我清楚的记得)Heinz Zemanek1959pre-ALGOL会议上是如何明确表达了他对是否应该赋予goto语句和赋值语句同样的语法基础的质疑。在一定程度上,我责备自己那时未能从他的意见中汲取教训。

        There mark about the undesirability of the go to statement is far from new. I remember having read the explicit recommendation to restrict the use of the go to statement to alarm exits, but I have not be enable to trace it; presumably, it has been made by C. A. R. Hoare. In[1, Sec. 3.2.1.] Wirth and Hoare together make a remark in the same direction in motivating the case construction: "Like the conditional, it mirrors the dynamic structure of a program more clearly than go to statements and switches, and it eliminates the need for introducing a large number of labels in the program."

        关于goto语句非必要的论述远不是新的观点,我记得有人明确建议只在跳转退出点时使用goto,但我找不到出处了;大概是C.A.R.Hoare吧。在【1,Sec. 3.2.1】中,WirthHoare在使用case结构时如是说:“像条件语句,它比goto语句和switch更清楚的描述了程序的动态结构,还消除了一大堆的labels”

       

        In[2] Guiseppe Jacopini seems to have proved the (logical)superfluousness of the go to statement. The exercise to translate an arbitrary flow diagram more or less mechanically into a jump-less one, however, is not to be recommended. Then the resulting flow diagram cannot be expected to be more transparent than the origin alone.

        在【2】中Guiseppe Jacopini似乎证明了个goto语句是逻辑上多余的。转换任意一流程图到无goto图的训练则不推荐,结果流程图不一定比原有的清晰。


References:

Wirth,Niklaus, and Hoare C. A. R. A contribution to the development of ALGOL. Comm. ACM 9 (June 1966), 413-432.

BÖhm, Corrado, and Jacopini Guiseppe. Flow diagrams, Turing machines andlanguages with only two formation rules. Comm. ACM 9 (May 1966),366-371.


EdsgerW. Dijkstra

Technological University

Eindhoven,The Netherlands

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值