#   # 60 PicoLisp Functions You Should Know - 4: Control Flow

## Loops and conditional statement

### Conditonal Statements

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 `and` and `or`.

``````: (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 `if`which is `ifn`. Other logical operators are `xor`, `nor` and `nand`. If you're not familiar with logical operators, consider to study basic Boolean Algebra before going on.

Besides `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:

• `ifn` is the negated form of `if`, i. e. the function is executed if the condition evaluates to NIL.

• `when` is 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 `when` is `unless`.

• `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 `cond` is `nond`.

### Loops

1. Let's start with `for`-Loops. In the easiest form, `for` takes 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
``````
2. The `while` loop 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.

Notice the `@` 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
``````
3. `do` is 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 `NIL`.

4. `loop`works 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.