When this matters
Choose a conditional by the shape of the question. It may be one yes/no test, several predicates, one value compared with fixed datums, or a side effect that should run only in one case. Remember that only #f is false.
See it run
(case 2 ((1) 'one) ((2) 'two) (else 'other))Observed result
twoRead the example
case evaluates 2 once, compares it with each listed datum using eqv?, and selects the second clause. The quoted symbol two is the result, and the else clause is not evaluated.
when runs its body in order only when the test is true and gives back the last value. unless does the opposite and runs when the test is false. So (when #t 42) is 42 and (unless #f 7) is 7. The path the test rules out produces no value at all.
guard is written (guard (variable clause ...) body ...). When the body raises, the error object is bound to the variable and the clauses are tried in order the way cond tries them. A clause head may be else.
How to reason about it
cond,case,and,or,when,unless,let*, namedlet,do, and quasiquote preserve pinned evaluation and tail positions.- Generated temporary names and hidden built-in operations cannot be captured or shadowed by user names.
casecompares datums witheqv?, and the false paths ofwhenandunlessproduce zero values.ifneeds all three parts. Drop the false arm and write(if #t 1)and you get E130.- A
condorcasewith noelseclause produces no value at all when nothing matches. Put that result where a value is required and you get E320. elseis not a reserved word. It only means something at the head of acond,case, orguardclause, so(define else 5)is accepted.- The
condarrow clause=>is not supported and raises E130. Thecasearrow clause has no diagnostic at all, so=>reads as a name and raises E300.
Choose quickly
| Form | Use it when | Result behavior |
|---|---|---|
if | there are exactly two branches | returns the selected branch |
cond | different predicates name several cases | returns the first matching clause |
case | one value is compared with fixed datums | evaluates the key once |
and / or | tests form a short-circuit chain | returns an operand value, not a coerced boolean |
when / unless | a one-sided effect is clearer | false path returns zero values |
A common mistake
There is no define-syntax or user macro expansion.
Current boundaries
- Bare
unquoteandunquote-splicingoutside quasiquote are static errors.
Keep going
The data-and-decisions lesson teaches the everyday forms. Derived Forms gives their exact normalization shapes.