Skip to content

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:

  1. Evaluate the next expression; if it is the last expression, it is the result.
  2. Otherwise, if it is True, evaluate the following expression as the result.
  3. 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.

  1. Which control word is redundant?

    Answer

    Clearly if is a special case of do in which E0 evaluates as a boolean.

  2. Rewrite the following without control words.

    if[a=0;b:42]
    if[a<>0;b:67]
    
    Answer

    b:$[a;67;42]
    
    or as 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 both a and b above can be vectors.

  3. Rewrite the following without control words.

    if[a=0;b:42;c:99]
    if[a<>0;b:67;c:142]
    
    Answer

    (b;c):$[a;67 142;42 99]
    (b;c):(67 142;42 99)a=0
    (b;c):?[a=0;42 99;67 142]
    
    Note the use of scalar extension with Vector Conditional, and of list assignment (since V4.1).