As well as the conventional branch arrow, APLX supports structured-control keywords for flow control, often making for more readable functions.
The structured control keywords are not part of the International Standards Organisation (ISO) specification of the APL language, but they are supported by a number of APL implementations including APLX.
The structured control keywords include:
Note: The general keyword :End can be use in place of any of :EndIf :EndFor :EndWhile :EndRepeat :EndSelect :EndTry
Using Control Structures
The keywords all begin with a colon character, and usually appear at the start of the line (APLX will automatically indent lines within a block for you). For example:
∇ITERATE N  :If N<0  'Negative argument not supported'  :Return  :EndIf  ...
You can also place a block on a single diamond-delimited line:
∇ITERATE N  :If N<0 ⋄ 'Negative argument not supported' ⋄ :Return ⋄ :EndIf  ...
Multi-line sequences can be nested to any depth, but single-line sequences cannot contain further nested control structures. Note: The single-line form cannot be used with :Try..:EndTry.
The APLX function editor prompts you with the correct indentation as you type. If you cut or paste lines, you can clean up the indentation from the Edit menu (or press Ctrl-I in Windows, Cmd-I under MacOS)
The supported set of structured-control phrases is as follows (items in square brackets are optional). You can end any sequence with :End rather than the more specific ending keyword shown. Note that in APLX, structured-control keywords are not case-sensitive when you enter them, but APLX will re-display them in the case shown.
Syntax::If <boolean expression>
[:ElseIf <boolean expression>]
The expression following the :If keyword is evaluated. If it is true, the block which follows it is executed, until an :ElseIf, :Else, :End or :EndIf is encountered, at which point execution transfers to the statement after the :End or :EndIf. If the expression is false, the same procedure is followed for any :ElseIf blocks in the sequence. If none of the tests is true, the :Else block (if any) is executed. It is permissible to have as many :ElseIf sections as you like.
For example, this function returns a string which depends on the value of B:
∇R←CLASSIFY B  :If B=0  R←'Zero'  :ElseIf B>0  R←'Positive'  :Else  R←'Negative'  :End ∇
You can also add :AndIf or :OrIf phrases after an :If or :ElseIf phrase. If you use :AndIf, each expression must be true for the block to be executed, whereas if you use :OrIf only one of them needs to be true. (The :AndIf and :OrIf conditional expressions are evaluated only if necessary). For example:
∇R←A CLASSIFY B  :If B=0  :AndIf A=0  R←'Both arguments are zero'  :ElseIf B=0  :OrIf A=0  R←'One argument is zero'  :Else  R←'Neither argument is zero'  :End ∇
Syntax::For <control variable name> :In <vector expression>
The control variable is assigned successive values from the vector expression and the loop is executed once for each value. The values can be of any type, not just integers. The vector expression is evaluated only once, at the start of the loop. For example:
:For W :In "It's" "Off" "To" "Work" ⋄ 'HiHo' W ⋄ :EndFor HiHo It's HiHo Off HiHo To HiHo Work
You can use the :Continue keyword within the loop to force premature termination of a particular iteration - execution continues at the top of the loop with the next value (if there is one). You can also use the :Leave keyword to exit the loop completely and continue execution with the line after the :EndFor.
Syntax::While <boolean expression>
If the boolean expression is true (value 1), the loop body is executed. At the end, control returns to the :While statement and the loop is re-executed as long as the boolean expression remains true.
∇Evaluate B  :While B>0  B←NextNode B  :EndWhile ∇
An alternative form allows a test at the end of the loop as well:
Syntax::While <boolean expression>
:Until <boolean expression>
The :Continue and :Leave keywords can again be used to force an early termination of a particular iteration or of the whole loop.
Syntax::Repeat [<integer expression>]
The loop body is repeated a maximum of N times, where N is the value of the integer expression (evaluated only once, at the start of the loop). If the integer expression is omitted, the loop is repeated for ever, unless terminated in another way. For example:
:Repeat 3 ⋄ ⎕TS ⋄ :EndRepeat 2002 7 30 14 36 2 228 2002 7 30 14 36 2 228 2002 7 30 14 36 2 228
The :Continue and :Leave keywords can again be used to force an early termination of a particular iteration or of the whole loop:
∇GUESS;VAL  'Guess a number'  :Repeat  VAL←⎕  :If VAL=231153  'You were right!'  :Leave  :EndIf  'Sorry, try again..'  :EndRepeat ∇
You can also end the loop with an :Until statement so that execution repeats only if a boolean expression remains true::Repeat [<integer expression>]
:Until <boolean expression>
[:CaseList <vector expression>]
The :Select expression can be any APL scalar or array. It is matched against each of the :Case expressions (or elements of the :CaseList expressions) in turn. If they match in value and shape (using the same rules as the APL
∇R←CLASSIFY B;⎕IO  ⎕IO←1  :Select B  :Case 0  R←'Scalar zero'  :Case 1⍴0  R←'Length 1 vector, value 0'  :CaseList ⍳10  R←'Scalar in the range 1 to 10'  :Else  R←'None of the above'  :EndSelect ∇ CLASSIFY 0 Scalar zero CLASSIFY 2 Scalar in the range 1 to 10 CLASSIFY 1⍴2 None of the above CLASSIFY 1⍴0 Length 1 vector, value 0
[:CatchIf <boolean expression>]
The block of code following the :Try keyword is executed, until either an error occurs, or a :CatchIf, :CatchAll, :End or :EndTry is encountered. (Unlike the other control structures, :Try...:EndTry blocks cannot be placed on a single line).
If no error has occurred within the :Try block, execution transfers to the line after the :End or :EndTry.
If an error occurs in the :Try block (either in the statements in this function, or in any functions called from it), control transfers to the first :CatchIf line, and the expression is evaluated. If it is true, the block of code following the :CatchIf is executed, and execution then resumes after the :EndTry or :End. If the expression is false, the same procedure is followed for any further :CatchIf blocks in the sequence. If none of the tests is true, the :CatchAll block (if any) is executed. It is permissible to have as many :CatchIf sections as you like.
Typically, you use the :CatchIf statement to catch specific types of error, by looking at
The :GoTo keyword (followed by a line label name) can be used to branch directly to a label. It is equivalent to using a conventional APL
The :Return keyword causes the current function execution to terminate. It is equivalent to a conventional APL branch to line 0.
Normally the :Continue and :Leave keywords apply to the current loop in which they are executed, so that if you have a loop nested within a loop, execution resumes at the start or end of the innermost loop. However, you can also name loops by including a label at the start line, and follow the :Continue or :Leave with the name to apply it to a particular level of nesting. In this example, if the :If clause is true, execution continues at line 9:
∇ITERATE;N  OUTER: :Repeat  :For N :In SAMPLES  :If INTERRUPTED  :Leave OUTER  :EndIf  ...  :EndFor  :EndRepeat  ...
If there is an error in the usage of structured keywords, APLX will report a
Note that APLX does not prevent you from fixing a function which is syntactically incorrect. However, the APLX editor will warn you of mismatched structured-control keywords if you select 'Clean up indentation' from the Edit menu (Ctrl-I in Windows, Cmd-I under MacOS).
Copyright © 1996-2010 MicroAPL Ltd