Control structures
Control structures can look like functions. They are not.
Control structures Cond $
, and the three control words do
, if
, and while
return results, as all q expressions do, but only the result of Cond is useful.
The other three return always and only the general null.
Use Cond for a result and control words for side effects.
As a good functional programmer, avoid side effects.
A control structure is followed by an expression list (E
) with one or more expressions.
Only the first expression (E0
) is certain to be evaluated; it must evaluate to an atom.
Conditionals
- Test expression
-
An expression evaluated as True or False.
Cond
The expression list of Cond $
contains an odd number of expressions, at least three, evaluated as follows:
- Evaluate the next expression; if it is the last expression, it is the result.
- Otherwise, if it is True, evaluate the following expression as the result.
- Otherwise, skip the following expression and go to (1).
Simple if/then/else constructions can be written concisely. In a script you can set out more complicated constructions as pairs of test and value expressions.
$[E0; E1; / if E0 then E1
E2; E3; / else if E2 then E3
E4; E5; / else if E4 then E5
..
En ] / else En
For setting a single value, Cond corresponds well to if/then/else logic.
If
If E0
evaluates as True, 1_E
are evaluated in turn; otherwise nothing is done.
if[a=0;.log.err"a is zero";'`zero];
Iteration
Do
E0
evaluates as an integer; 1_E
are evaluated in order that many times.
q)do[0;A:999] / don't do it
q)A
101
q)do[0b;A:999] / still don’t do it
q)A
101
q)do[5;A+:1] / do it 5x
q)A
106
q)do["5";A+:1]
q)A
159
q)"j"$"5" / HOW many times?
53
While
If E0
evaluates as True, 1_E
are evaluated.
This is repeated until E0
evaluates as False.
control word | test | consequence |
---|---|---|
do | E0 > 0 | evaluate 1_E E0 times |
if | E0 is True | evaluate 1_E once |
while | E0 is True | evaluate 1_E; try E0 again |
Conditional functions
For mapping a list of values to a range of results, consider the Vector Conditional operator and the Case iterator.
Exercises
No peeking.
Attempt each exercise before looking at its answer.
The exercises clarify your thinking. Reading answers does not.
-
Which control word is redundant?
Answer
Clearly
if
is a special case ofdo
in whichE0
evaluates as a boolean. -
Rewrite the following without control words.
if[a=0;b:42] if[a<>0;b:67]
Answer
or asb:$[a;67;42]
b:67-25*not a
. Rewriting a conditional in this form lets you vectorise it. While a test expression must evaluate to an atom, either or botha
andb
above can be vectors. -
Rewrite the following without control words.
if[a=0;b:42;c:99] if[a<>0;b:67;c:142]
Answer
Note the use of scalar extension with Vector Conditional, and of list assignment (since V4.1).(b;c):$[a;67 142;42 99] (b;c):(67 142;42 99)a=0 (b;c):?[a=0;42 99;67 142]