Control Flow in Racket | Schema Programming Part 4
Unlike imperative languages that rely on for and while loops, Racket uses conditional expressions and recursion to control the flow of execution. Mastering these constructs is key to writing "Schematic" code.
Advertisement
Conditionals: decisions, decisions
1. The Simple if
The if form in Racket is an expression. It looks like (if test then else).
(define x 10)
(if (> x 5)
"Greater than 5"
"Less or equal to 5")
Note: The else branch is mandatory in some dialects, but in Racket semantics, it's an expression that must return a value.
2. The Versatile cond
For multiple conditions, standard nested ifs get messy. Racket provides cond (conditional), which is like switch or else if chains but more powerful.
(define (classify-number n)
(cond
[(< n 0) "Negative"]
[(= n 0) "Zero"]
[(> n 0) "Positive"]))
Square brackets [] are often used in cond clauses for readability, but they are interchangeable with parentheses ().
3. when and unless
When you only care about the "true" case (often for side effects), use when.
(when (file-exists? "log.txt")
(display "File found!")
(newline))
unless is the opposite: executes the body if the condition is false.
Pattern Matching with match
Racket has a powerful pattern matcher that can destructure complex data.
(define (describe-list lst)
(match lst
['() "Empty list"]
[(list x) (format "List with one element: ~a" x)]
[(list x y) (format "List with two elements: ~a and ~a" x y)]
[_ "A longer list"]))
This is much more expressive than checking lengths and accessing elements manually.
Advertisement
Boolean Logic
Combine conditions using and, or, and not.
(and (> 5 2) (< 5 10)) ; #t
(or (= 1 1) (= 2 3)) ; #t
(not #t) ; #f
Tip: and and or simplify (short-circuit).
Recursion as Looping
In Racket, we don't usually write for (int i=0; i<10; i++). We use recursion. But isn't that slow?
Not in Racket! Racket supports Tail Call Optimization (TCO). If the recursive call is the last thing a function does, it reuses the current stack frame, making it just as efficient as a while loop in C.
Example: Summing a List (Tail Recursive)
To ensure tail recursion, we often use an accumulator.
(define (sum-list lst acc)
(if (empty? lst)
acc
(sum-list (rest lst) (+ (first lst) acc))))
(sum-list '(1 2 3 4) 0) ; Returns 10
Summary
- Use
iffor simple binary choices. - Use
condfor multi-way branches. - Use
matchfor structural decisions. - Embrace recursion for looping.
Next up, we unlock the real power of Functional Programming: Higher-Order Functions.
Which Racket form is best suited for handling multiple conditions?
Md Nasim Sheikh
Software Developer at softexForge