The language contains multiple special forms for managing control flow.
You can evaluate multiple expressions together using
> (do (print "Number: ") (+ 1 2)) Number: 3
The value of the whole expression is the value of the last expression.
Conditional evaluation is accomplished with the
if expression which is of the form
(if test consequent alternate). If test evaluates to truthy value, consequent is evaluated and returned. If test evaluates to falsy value, alternate is evaluated and returned:
> (if (< 1 2) "yes" "no") "yes"
If alternate is not provided, null is returned in its place:
> (if (str? 1) "string") null
and form returns the first expression that evaluates to falsy value:
> (and 2 true "str" 0 3) 0
or form returns the first expression that evaluates to truthy value:
> (or 0 false 3 5) 3
or return true and false respectively:
> (and) true > (or) false
Cond, case and case-strict
When you have more than two possible paths of execution, it is convenient to use the
Consider the following defined for these examples:
> (def n 4) 4
cond, the first item of each argument is evaluated. If it evaluates to truthy value, the following expression is evaluated and returned:
> (cond ((= n 2) "two") ((= n 4) "four") ((= n 6) "six")) "four"
case, the first argument is evaluated, and then it is matched against the first item of the remaining arguments. If there is a match, the following expression is evaluated and returned:
> (case (% n 2) (0 "even") (1 "odd")) "even"
Note that the values to match against,
1 in the above example, are not evaluated.
case-strict is similar, but uses strict comparison:
> (case n ("4" "string") (4 "integer")) "string" > (case-strict n ("4" "string") (4 "integer")) "integer"
case can have an
else form which is matched if nothing else matched up to that point:
> (cond ((< n 2) "small") (else "big")) "big" > (case (% n 2) (1 "odd") (else "even")) "even"
case can have more than one expression which is evaluated after a successful match:
> (cond ((int? n) (print "Number: ") n)) Number: 4
The arguments to
case can be also be given as vectors:
> (cond [(int? n) "integer"] [else "other"]) "integer"
If no match is found, and
else is not defined,
case return null.
Looping is accomplished with the
while expression which is of the form
(while test expr1 expr2 ...). The test is evaluated at the beginning of each iteration and if it returns truthy value, the remaining expressions are evaluated. The value of the whole expression is the value of the last evaluated sub-expression.
> (let (i 5) (while (> i 0) (print i) (def i (dec i)))) 543210
Although the above example illustrates how to use
while, this type of code is discouraged. Generally it is recommended to use recursion instead of iteration in these type of scenarios. Usually it results in cleaner code as well. The
while expression is better suited for something like the main loop of a program.