# Controlling evaluation

' ': /: \:   each peach prior     $[x;y;z] Cond \ / scan over ?[x;y;z] Vector Conditional.[f;x;e] Trap : Return do exit @[f;x;e] Trap-At ' Signal if while Evaluation is controlled by • iterators (maps and accumulators) for iteration • conditional evaluation • explicit return from a lambda • signalling and trapping errors • control words ## Iterators Iterators are the primary means of iterating in q. ### Maps The maps Each, Each Left, Each Right, Each Parallel, and Each Prior are iterators that apply values across the items of lists and dictionaries. ### Accumulators The accumulators Scan and Over are iterators that apply values progressively: that is, first to argument/s, then progressively to the result of each evaluation. For unary values, they have three forms, known as Converge, Do, and While. ### Case Case control structures in other languages map values to code or result values. In q this mapping is more often handled by indexing into lists or dictionaries. q)show v:10?v1v2v3 / values v1v1v3v2v3v2v3v3v2v1 q)r1r2r3 v1v2v3?v / Find r1r1r3r2r3r2r3r3r2r1 q)(v1v2!r1r2) v / dictionary: implicit default r1r1r2r2r2r1 q)r1r2default v1v2?v / explicit default r1r1defaultr2defaultr2defaultdefaultr2r1  The values mapped can be functions. The pseudocode for-each (x in v) { switch(x) { case v1: abc,x; break; case v2: string x; break; default: x; } }  can be written in q as q)((abc,;string;::) v1v2?v)@'v abcv1 abcv1 v3 "v2" v3 "v2" v3 v3 "v2" abcv1  and optimized with .Q.fu. See also the Case iterator. ## Conditional evaluation Syntax: $[x;y;z]

Cond returns z when x is zero; else y.

Two arguments are evaluated: x and either y or z.

Vector Conditional does something similar for lists of arguments, but evaluates all three arguments. It should be used in qSQL queries, which do not support Cond.

## Explicit return

Syntax: :x

The result of a lambda is the last expression in its definition, unless the last expression is empty or an assignment, in which case the lambda returns the generic null ::.

:x has a lambda terminate and return x.

q)foo:{if[0>type x;:x]; x cross x}
q)foo 2 3
2 2
2 3
3 2
3 3
q)foo 3
3


## Signalling and trapping errors

Signal will exit the lambda under evaluation and signal an error to the expression that invoked it.

q)goo:{if[0>type x;'type]; x cross x}
q)goo 2 3
2 2
2 3
3 2
3 3
q)goo 3
'type
[0]  goo 3
^


Trap and Trap At set traps to catch errors.

## Control words

do

evaluate some expression/s some number of times

exit

terminate kdb+

if

evaluate some expression/s if some condition holds

while

evaluate some expression/s while some condition holds

Iteration

Control words are little used in practice for iteration. Iterators are more commonly used.

Iterators:
Maps – Case, Each, Each Left, Each Right, Each Parallel, Each Prior
Accumulators – Converge, Do, While, Scan, Over

### Common errors

Control words are not functions, and return as a result only Identity.

A common error is forgetting to terminate with a semi-colon.

The result of if, do, and while is Identity, (::), which allows one mistakenly to write code such as a:if[1b;42]43 (instead use Cond), or a:0b;if[a;0N!42]a:1b` – the sequence is not as intended!