A New Life For ∇: Structure Control
Vector 17:4, page 125
Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 125
1. Introduction¶
In the years after Edsgar Dijkstra wrote his complaint "GOTO considered Harmful" (Dijk68), an important discussion followed among software professionals regarding structured programming. APL did not join in this discussion. As a result of that discussion, program languages implemented concepts to enable programmers to program in a structured way. APL however remained in splendid isolation, cherishing its beloved jump "→".
This is very unfortunate because the tools you have influence the way you think. The essence of the discussion was not so much about better tools, but about thinking. Having jumps let you think in flow whereas structured concepts make you think in structure (blocks if you like) which is much better.
It was only in 1978 that Wiedman (Wie78), Reeves and Besemer (Ree78) started the discussion in APL. After their initiative, many authors followed with proposals to add control structures (see long list of references compiled by De Kerf (Ker86)) but APL vendors effectively ignored this. Finally, in 1994 Manugistics came with an implementation that copied the concepts as well as the keywords of conventional languages. A few years later in 1996, Dyalog APL followed suite and so did J; all of them copying the concepts and the keywords.
To my opinion, this is not good. Granted, these control structures have been essential improvements to hitherto unstructured languages and these concepts are worthwhile tools to structure a program. But why should APL slovenly copy these implementations lock, stock and barrel? After all, "COS(X)", "MIN(X,Y)" and "CEIL(X)" are nowadays also part of the standard repertoire of most languages (and rightfully so), but nevertheless APL programmers are much happier with "2○X", "X⌊Y" and "⌈X".
My point is that APL should copy the ideas of useful concepts (and possibly improve upon them), but not copy the way such concepts are implemented and certainly not a keyword implementation. Instead, APL should have chosen an APL-lish implementation using symbols instead of keywords and preferably one powerful symbol that does it all.
2. A Better Structure Control¶
APL2C has chosen such an APL-lish implementation for structure and structure control. APL2C is an APL implementation that is developed by T.Otto (Ott00). It is a fully functional APL2-type implementation. The name APL2C is chosen because one can produce C-source code from a workspace. This enables programmers to modify the C-code at will, add other modules if needed, and at the end compile the whole combination into an executable.
The implementation for structure control is based on a further development of my ideas as published in Bat82-Bat94. In APL2C the symbol that does all the structuring and its control is the del "∇" which for that reason will be called control. The choice of this symbol agrees well with its original purpose to indicate start and end of function definition. As Willhoft argued, for a long time the only block available in APL was a function, so "∇" seems a suitable symbol for blocks (Wil93). This does not clash with the function definition anymore because function definition is done by )EDIT or by double click (as is common in most Windowing implementations). Symbol control is used monadically to indicate the beginning of a block and it is used niladic to mark the end of a block.
Iteration¶
An example will show how this works. We begin to show iteration. The following code:
is a block that will be executed 9 times; first the expression at the right of the monadic control is executed and the resulting value 9 will instruct control to print out 9 times two lines with HALLO on the odd lines and WORLD on the even lines.
Condition¶
The previous example showed iteration, but condition is quite similar. For loops, the expression at the right of control is an integer indicating how many times to execute the block, for conditions it suffices when the integer is either one or zero. For example to do something only if FLAG is non-zero you could program:
While¶
The examples above have shown how condition and iteration is implemented in APL2C. The while-construction is implemented in a similar way. After all, a while-construct is an iteration, but an iteration that is executed as long as the controlling expression is true. Therefore the implementation is identical to the fixed iteration, however, to tell APL to recheck the controlling expression a negative value is used.
For example to read input until the user enters an empty line:
Another example that codes an iteration until the result does not change any more is:
OLD←1+NEW←INITIALVALUES ⍝ initially different values
for NEW and OLD
∇-OLD≢NEW
OLD←ANALYSE NEW←OLD
∇
Alternatives¶
What about alternatives like IF-ELSE and SELECT? To program alternatives APL2C needs a vector for the right argument of control. This vector prescribes what to do for each alternative. The alternatives in the block are marked by a label-less colon ":". If the number of alternatives do not match the length of the vector, APL2C returns a LENGTH ERROR. An example will illustrate this:
This will print VARIABLE if the ∇-expression yields 1 0, it prints FUNCTION if the expression yields 0 1 and it will print nothing if the expression is 0 0. Just hypothetically, imagine that the ∇-expression yielded "¯2 7". In that case APL2C would have printed 2 times the word VARIABLE, 7 times the word FUNCTION and after that (because of the negative number ¯2) APL2C would execute the ∇-expression again.
Nesting¶
It is no problem to create nestings in APL2C. Just to wrap the whole idea up in one complicated (not so realistic) example, imagine the following code:
If CN get the value ¯2 0 then action1 and action2 are done twice after which APL2C does the expression in control1 again.
If CN get the value 0 3 then action3 and action4 are done, and done another 9 times to satisfy the value 10 in control2, and this is done another 2 times to satisfy the 3 in control1. As there was no negative number in control1, this ends the total block.
Iteration counter¶
In the previous examples, the iterations did not need a variable to keep track of the iterations. Sometimes you do not need one, but there are often occasions where it is convenient to know the iteration number. If so, you could of course explicitly program this, but it is more convenient if such a counter is available.
The iteration count can be found in Iteration Counter "+ZIC". This variable is a 2-row matrix with one row for the current iteration counter, and the second row for its terminal value. So within one single block, it is a one-column matrix. With nested blocks "ZIC[;1]" gives the current counter and the final value for the innermost block and the last column gives the counter and final value for the outer-most block.
For example:
∇5 3 ¯8 0
: ~~~~~ ⍝ here ⎕IC is 2 1⍴(1-5),5
:∇4 ⍝ here ⎕IC is still 2 1⍴(1-3),3
~~~~~ ⍝ but here ⎕IC is 2 2⍴(1-4),(1-3),4,3
∇
:~~~~~ ⍝ here ⎕IC is 2 1⍴(1-8),¯8
:~~~~~ ⍝ alternative 4 is never executed
∇
Single-line shortcut¶
For small actions, a shorter alternative is available for iterations and conditions. This is the single-line alternative where control is used dyadically with controlling expression at the right and the action at the left. For example:
LEFT←3∇2≠⎕NC'LEFT' ⍝ Only assignment ifor missing LEFT
⎕←'Thank you...'∇1000 ⍝ Thousand times thanks
ANALYSE IN∇-0≠⍴IN←,⍞ ⍝ Analyse as long as input is given
Formatting¶
The examples that were presented not only showed the working of control, but also how APL2C formats the blocks. Each block is indented one space and the colon for alternatives is outdented so as to show to which control they belong.
3. Conclusion¶
You have seen how APL2C handles structure and its control. In this implementation all structured control concepts are blended together in one simple, but very powerful, construct control. This takes the essence of structured control, but implements it more in the spirit of APL. The result are programs where structure is better recognized than in current alternatives.
For a more complete example, the Vector website shows two programs that were structured to begin with. Both programs are shown in their original programming style as well as a remake using control. It shows how the programs get shorter and more comprehensible.
If you are interested in experiencing how this works you could download a demo version of APL2C. You can find more information as well as a full featured trial version with a time limit of half a year, at website: //www.apl2c.com.
4. Literature¶
- Bat82
- Batenburg,F.H.D.van(1982): New control structures in APL. Quote Quad.13(2)15-20
- Bat85
- Batenburg,F.H.D.van Prins,R.(1985): QL/APL: A leap back - or forward? Vector 2(2)115-117
- Bat88
- Batenburg,F.H.D.van(1988): The Code-line: A "New" Structured Concept. Quote Quad.19(2)14-19
- Bat91
- Batenburg,F.H.D.van (1991): L-one-two-three (L1:...L2:...L3:...) considered harmful. Proc. APL91 p.330-337
- Bat94
- Batenburg,F.H.D.van (1994): Restriction riddance: more power to parentheses. Quote Quad 25(1)220-224.
- Dijk68
- Dijkstra,E.W.(1968): GOTO statement considered harmful. ACM Comm. 11(3)147-148
- Ker86
- Kerf,J.L.F. De (1986): APL and structured programming: an annotated biography. APLCAM 8(2)340-363
- Ott00
- Otto,T.(2000): Oral presentation at APL conference 2000
- Ree78
- Reeves,A.P. Besemer,J.(1978): Special control structures in APL. Quote Quad.9(2)23-31
- Wie78
- Wiedman,C.(1978): Whither (wither?) control structures. Quote Quad 9(2)21-22
- Wil93
- Willhoft,R. (1993): Structured APL: a proposal for block structured control flow in APL. Proc APL93 p.304-315
F.H.D. van Batenburg
Theoretical Biology of Leiden University
http://wwwbio.LeidenUniv.nl/~Batenburg/index.html