Topic: wftk -- Process definition: iteration[ wftk home ] [ process definition ] [ discussion ]
The iteration construct is based on a presentation by Charles T. Zahn
in 1974, which Donald Knuth described in a paper in the same year and republished in
his book Literate Programming in 1992. It's a very general loop structure which
covers "plain old" loops as well, so that we get a lot of freedom in building loops without
having to write much code to interpret them.
The whole thing is based on the situation. The situation is basically a named break, and after the loop you write handlers which process the situations generated. This avoids the common problem of, say, a for loop with a break -- when you exit the loop, you commonly test the loop index to see whether it's within the bounds; if it is, you know the loop exited via the break, and not by simply running through the whole range of the index. This results in code that's hard to understand, sometimes. But it gets worse when you have two or more breaks. Then you have you declare and set a flag to determine which break was actually hit.
Well, this iteration construct pretty much does that for you. Here's how it
So all we need are the situation and handle tags:
The situation tag can be placed in a sequence or a parallel block. If it's in a sequence, it breaks immediately and no further sequential actions will be taken. If in a parallel, since all the actions are started simultaneously, we obviously can't stop processing things that are already started; so all the actions will run to completion, synchronize at the end of the block, and the block will then terminate and the handler will be invoked. Note that a non-repeating sequence can be terminated with a situation perfectly naturally, but a non-repeating parallel block with a situation will run in exactly the same way as one without a situation. The only difference is that you can use the situation as a flag, so that the appropriate handler will run.
If no handler is provided immediately following the block in which a situation occurs, then the parent block is terminated with that situation, and so on until the situation does have a handler. This provides a neat solution to the problem of how to break nested loops.
Something else we'll need for loops is an index variable. The index variable simply counts
the number of times we've been around the loop, and we can name it whatever we like. The
syntax for this is
Finally, I'm toying with the idea of providing nonbreaking situations. These would be analogous
to flags and would provide a dandy way to flag completion of particular segments of a block.
Since parallelism will make it possible for multiple situations to be activated at once
anyway (thus making it necessary to maintain a list of situations active) I might as well
exploit that mechanism. So
The objection will probably be raised that this design is too complicated. However, it's really easier than having separate for and while loops, for instance, because there is less to parse and to keep track of. And we really do need iteration to do nearly anything outside of toy problems. The inclusion of parameters with the situation is more complicated than absolutely necessary, so the prototype probably won't have parameters on situations. It may turn out to be more than we need anyway. We'll see.
Bibliography and extraneous note
It's interesting that work like this, done in the early 70's, was completely ignored by subsequent language development. The problem was that Algol and Pascal had already been developed. C was based on those, leaving no particular motivation to look at new structures. And then of course in the 80's, coming a little out of left field, object-oriented programming was the leading movement, and the programming structures available to the programmer actually writing the object methods was based on C, and again new constructs were uninteresting.
Read Knuth's article for an interesting exploration of different ways of handling the goto problem, especially in regards to loops.