kers@hplb.hpl.hp.com (Chris Dollin) (02/28/90)
All thois discussion about loop structures (here and in comp.lang.c) reminds me of my own favourite loops structures. The first is the n-and-a-half times loop: repeat Part1; [until|while] Condition [do Part2] endrepeat; which means "do Part1. If Condition is true (until) or false (while), the loop is done. Otherwise do Part2 and go back to repeat." Of course Parts 1 & 2 are optional. Thus a "traditional" while loop is just repeat Condition do PartOnly endrepeat and the Pascal "until" is just repeat PartOnly until Condition endrepeat The second is a variation of Hehner's variation on Dijkstra's guarded commands: loop Name; Stuff endloop where Stuff may contain the command "Name again", which causes execution to resume at the top of the loop; the again-command MUST appear in a tail-call position (so it can be given procedure-call semantics, but can be implemented as a goto. (It is possible to incorporate parameters into this notation.) I have found that this notation is convenient for "all" those loops that would otherwise need breaks, boolean variables, and other machinery. It is, of course, just controlled tail-recursion. Hehner's observation (about Dijkstra's guarded loops, and by extension other forms of loop), with respect to "abnormal" exits, is (I mangle freely), that when one wishes to do some more (of the loop), one says *nothing*, but when one wishes to do no more (eg break) one says *something*. The loop-construct above has the opposite property: when one has more to do, one says so, and when there is no more to be done, one is silent. Interestingly, when I coded up this syntax in Pop11, the error I most often made was loops *terminating unexpectedly*, rather than *not terminating* - I left off the again's. Probably a lifetime of writing loops in the implicit style. Regards, Kers. | "You huff and you puff, but to no avail."