True is spelled #true or #t. False is spelled #false or #f. When used in a conditional expression, every value other than #false counts as true. There are no “falsish” values.
1 2 3 4 5 6 7
That was easy.
If you need to flip a Boolean from true to false or vice versa, use not.
1 2 3 4
and and or work in the usual short-circuiting way. That is, they stop when they reach a false or true value, respectively. So nothing bad will happen when you run these, because the second condition on each line is never reached:
Can be written more compactly:
See loops for other convenient forms of and and or.
if has one conditional expression followed by two result expressions—the first is evaluated if the condition is true, otherwise the second is evaluated. If you need multiple expressions in a branch, you can put them inside an empty let.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
If you only need one branch, use when. + Or its logical inverse, unless. Like if, when starts with a conditional expression. Unlike if, the body of when can contain any number of expressions. If the condition is true, the last body expression is returned as the result. If the condition is false, the whole when expression returns <#void>, a special constant used to signal the absence of a result.
cond supports any number of condition branches, and an optional else branch. cond evaluates the condition on the left side of each branch, and stops at the first one that evaluates as true (precisely, the first one that’s not #false). Then it evaluates the right side of the branch. Like when, the right side can have any number of expressions, and only the last expression is returned as the result. If no branches match, you get <#void>.
cond offers a couple of tricks that if and when do not.
First, if you omit the right side of a cond branch, the value of the conditional will be used as the return value:
Second, you can capture the conditional value and use it on the right side of the branch with the => operator. The right side of the branch must be a function that accepts one argument. The return value of the cond is the function applied to the conditional value. This is useful when the conditional relies on an operation that’s expensive, or can only be done once.
case creates a conditional that compares a value against lists of literal values. At the top is the value to be compared. Like cond, a series of branches follow. If the value is equal? to one of the items in the list on the left, then the right side of the branch is evaluated and returned as the result. An optional else branch catches anything else:
1 2 3 4 5 6 7 8 9 10 11
For reasons unclear, the left-hand lists don’t use a ' prefix; they simply behave as if there were one already there.
match is a more general version of case. The basic form is the same: the value to be matched goes at the top, and a series of branches follow. If the value matches the pattern on the left-hand side of a branch, the right-hand side is evaluated and returned as the result.
Unlike case, match supports a wider pattern vocabulary that can match literal values, but also , , , , and other values. Moreover, match can also assign elements of the match to internal variables for further processing:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
(struct thing (x y)) (define (m in) (match in ["foo" 'got-foo] ; literal match [(? number?) 'got-number] ; predicate match [(list a b c) (list b)] ; list match + assignment [(thing i j) (+ i j)] ; structure match + assignment [_ 'no-match])) ; catches anything else (m "foo") ; 'got-foo (m 42) ; 'got-number (m (list 1 2 3)) ; '(2) (m (thing 25 52)) ; 77 (m "bar") ; 'no-match