Next, we will explore conditional statements. Let's start with the
if statement. It is quite straightforward:
: (if (> 4 3) (println 'OK) (println 'Bad)) OK -> OK
First comes the condition, then what is supposed to happen if the statement is fulfilled, then what happens if it is not fulfilled.
If we have more than one condition, we can connect them with
: (if (and (> 4 2)(> 4 3)) (println 'OK) (println 'Bad)) OK -> OK : (if (or (> 4 2)(> 4 5)) (println 'OK) (println 'Bad)) OK -> OK
To negate a condition, you can use
not, but usually it is more efficient to use the negated form of
ifn. Other logical operators are
nand. If you're not familiar with logical operators, consider to study basic Boolean Algebra before going on.
if, there are some alternative control flow options that might be more elegant in some specific use cases (in principle, they could be replaced by nested
if-clauses and Boolean Algebra). For details, refer to the documentation:
ifnis the negated form of
if, i. e. the function is executed if the condition evaluates to NIL.
whenis very similar to
if, except that it accepts more than just one function to execute if the condition evaluates to non-NIL. The negated form of
cond: Multi-way conditional: If any of the conditions evaluates to non-NIL, the program is executed and the result returned. Otherwise (all conditions evaluate to NIL), NIL is returned. The negated form of
Let's start with
for-Loops. In the easiest form,
fortakes a symbol and an integer. Then it is counted from 1 until the integer value is reached. Alternatively, a list can be used. For each iteration, the next item in the list is used.
: (for N 5 (printsp N)) 1 2 3 4 5 -> 5 : (for X (1 a 2 b) (printsp X)) 1 a 2 b -> b
whileloop is executed as long as the condition is evaluated to non-NIL. Example: Read console input as long as its not NIL and print out the output.
@symbol: it is a very useful symbol that stores the value of the last evaluation (it also has some other meanings, read here if you want to know more).
: (while (read) (println 'got: @) ) abc got: abc 1234 got: 1234 NIL -> 1234
dois a so-called counting loop, which means that it runs a defined number of times. The number of repetitions is set as argument:
: (do 4 (printsp 'OK)) OK OK OK OK -> OK
Additionally, it is possible to set an exit condition to exit the loop if the condition is fulfilled. For example:
: (do 2 (printsp 'OK) (T (= 3 3) (printsp 'done))) OK done -> done
The loop is exited already after the first iteration, because the exit condition
(T (= 3 3) (printsp 'done))reads like: "If (3=3) is true, then stop the loop and print 'done'". Another example:
: (do 2 (printsp 'OK) (T (< 3 3) (printsp 'done))) OK OK -> NIL
Here the exit condition (
< 3 3) is never true, so the iteration runs two times and then returns
loopworks very similar to
do, except that it has no defined number of iterations. See the following example:
- The variable N is set to 3, then the loop is started.
- The value of N is printed.
- The ending condition reads like "Is it true, that (N-1) equals zero?".
- If it is true, it returns "done" and exits the loop.
: (let N 3 (loop (prinl N) (T (=0 (dec 'N)) 'done) ) ) 3 2 1 -> done
Now we have covered the most basic use cases of input/output-functions and loops. In many cases, there are further options available that we didn't cover here. For further information, you can always refer to the official documentation.