Dyalog Primer - Control Flow
Exploration⎕vr¨'oddoreven' 'sfor' 'mfor' 'select'
∇ z←oddoreven w
 :If 2|w
∇ ∇ z←a sfor w;n
 :For n :In ⍳10
∇ ∇ z←a mfor w;n;m;⎕IO
 :For (n m) :InEach (⍳w)(÷⍳w)
 z,←⊂a*n m
∇ ∇ z←a select w
 :Select a
 :Case 'square'
 :Case 'root'
2 sfor 52
3 sfor 5
⊃2 mfor 5
'square' select 2
'root' select 2
'boot' select 2
control structures of Dyalog resemble those common in scalar languages.
structures can only be used in traditionally-defined functions and
operators (not in dynamic functions/operators or in the session).
can be used to clarify the structure of your code, but there is a
potential price to be paid.
price gets paid if you start using "scalar thinking" especially to loop
your way through vectors and higher-dimension arrrays - because APL is
an interpreted language, which means that it does two things every time
it meets a line of code:
- Figure out what
- Actually do it.
why it's sensible to ask yourself whether there's a directly-codable
array solution or whether the each operator is an alternative to a :For
construct. And to use the tools described in the Performance
- Notice also the pernicketyness of :If (it
needs a single-valued expression to decide what to do) and :Select
(where there has to be a complete match - content and shape - between
value and variable).
the olden days of APL all there was to direct execution to different
parts of a defined function/operator was a branch arrow (→,
used with line labels - except in cases of criminal insanity).
You'll still see a lot of old code that contains branch
and line labels - you shouldn't need to write anything like that today. This also applies to the :GoTo control word.
- Control Structures (Dyalog Language Reference)
- :For :Hold :If :Repeat :Select :Trap :While :With
- :AndIf :Case :CaseList :Else :ElseIf :OrIf :Until
- :EndFor :EndHold :EndIf :EndRepeat:EndSelect :EndTrap :EndWith :EndWhile
- :Continue :GoTo :Leave :Return
these exercises, the assumption is that functions will be defined
"traditionally" - also note that while there may be solutions which
don't require control structures (and they may or may not be "better")
we're looking to explore control structures here...
a defined function for calculating square roots; it should fail if any
element of the argument is negative, returning an empty vector as the
result in this case.
- Write a defined function to return the nth Fibonacci number.
- Write a defined function which obtains a file name from the user; the file must not previously exist.
- Write an ambivalent function which uses a default value when the left argument is missing.
- Write a defined function which processes its right argument differently depending on the value of the left argument.