4.2.1 Conditionals

syntax: (cond clause1 clause2 )
auxiliary syntax: else
auxiliary syntax: =>

Syntax: Clauses take one of two forms, either

(test expression1 )

where test is any expression, or

(test => expression)

The last clause can be an “else clause”, which has the form

(else expression1 expression2 ).

Semantics: A cond expression is evaluated by evaluating the test expressions of successive clauses in order until one of them evaluates to a true value (see Booleans). When a test evaluates to a true value, the remaining expressions in its clause are evaluated in order, and the results of the last expression in the clause are returned as the results of the entire cond expression.

If the selected clause contains only the test and no expressions, then the value of the test is returned as the result. If the selected clause uses the => alternate form, then the expression is evaluated. It is an error if its value is not a procedure that accepts one argument. This procedure is then called on the value of the test and the values returned by this procedure are returned by the cond expression.

If all tests evaluate to #f, and there is no else clause, then the result of the conditional expression is unspecified; if there is an else clause, then its expressions are evaluated in order, and the values of the last one are returned.

(cond ((3 2'greater)
      ((3 2'less))greater
(cond ((3 3'greater)
      ((3 3'less)
      (else 'equal)equal
(cond ((assv ''((1) (2))) => cadr)
      (else #f)2
syntax: (case key clause1 clause2 )

Syntax: Key can be any expression. Each clause has the form

((datum1 ) expression1 expression2 ),

where each datum is an external representation of some object. It is an error if any of the datums are the same anywhere in the expression. Alternatively, a clause can be of the form

((datum1 ) => expression)

The last clause can be an “else clause”, which has one of the forms

(else expression1 expression2 )

or

(else => expression).

Semantics: A case expression is evaluated as follows. Key is evaluated and its result is compared against each datum. If the result of evaluating key is the same (in the sense of eqv?; see Equivalence predicates) to a datum, then the expressions in the corresponding clause are evaluated in order and the results of the last expression in the clause are returned as the results of the case expression.

If the result of evaluating key is different from every datum, then if there is an else clause, its expressions are evaluated and the results of the last are the results of the case expression; otherwise the result of the case expression is unspecified.

If the selected clause or else clause uses the => alternate form, then the expression is evaluated. It is an error if its value is not a procedure accepting one argument. This procedure is then called on the value of the key and the values returned by this procedure are returned by the case expression.

(case (2 3)
  ((2 3 5 7'prime)
  ((1 4 6 8 9'composite))composite
(case (car '(c d))
  ((a'a)
  ((b'b))unspecified
(case (car '(c d))
  ((a e i o u'vowel)
  ((w y'semivowel)
  (else => (lambda (xx)))c
syntax: (and test1 )

Semantics: The test expressions are evaluated from left to right, and if any expression evaluates to #f (see Booleans), then #f is returned. Any remaining expressions are not evaluated. If all the expressions evaluate to true values, the values of the last expression are returned. If there are no expressions, then #t is returned.

(and (2 2) (2 1))#t
(and (2 2) (2 1))#f
(and 1 2 ''(f g))(f g)
(and)#t
syntax: (or test1 )

Semantics: The test expressions are evaluated from left to right, and the value of the first expression that evaluates to a true value (see Booleans) is returned. Any remaining expressions are not evaluated. If all expressions evaluate to #f or if there are no expressions, then #f is returned.

(or (2 2) (2 1))#t
(or (2 2) (2 1))#t
(or #f #f #f)#f
(or (memq ''(a b c))
    (3 0))(b c)
syntax: (when test expression1 expression2 )

Syntax: The test is an expression.

Semantics: The test is evaluated, and if it evaluates to a true value, the expressions are evaluated in order. The result of the when expression is unspecified.

(when (1 1.0)
  (display "1")
  (display "2"))unspecified
           and prints 12
syntax: (unless test expression1 expression2 )

Syntax: The test is an expression.

Semantics: The test is evaluated, and if it evaluates to #f, the expressions are evaluated in order. The result of the unless expression is unspecified.

(unless (1 1.0)
  (display "1")
  (display "2"))unspecified
           and prints nothing
syntax: (cond-expand ce-clause1 ce-clause2 )

Syntax: The cond-expand expression type provides a way to statically expand different expressions depending on the implementation. A ce-clause takes the following form:

(feature requirement expression )

The last clause can be an “else clause”, which has the form

(else expression )

A feature requirement takes one of the following forms:

  • feature identifier
  • (library library name)
  • (and feature requirement )
  • (or feature requirement )
  • (not feature requirement)

Semantics: Each implementation maintains a list of feature identifiers which are present, as well as a list of libraries which can be imported. The value of a feature requirement is determined by replacing each feature identifier and ‘(library library name)’ on the implementation’s lists with ‘#t’, and all other feature identifiers and library names with ‘#f’, then evaluating the resulting expression as a Scheme boolean expression under the normal interpretation of and, or, and not.

A cond-expand is then expanded by evaluating the feature requirements of successive ce-clauses in order until one of them returns #t. When a true clause is found, the corresponding expressions are expanded to a begin, and the remaining clauses are ignored. If none of the feature requirements evaluate to #t, then if there is an else clause, its expressions are included. Otherwise, the behavior of the cond-expand is unspecified. Unlike cond, cond-expand does not depend on the value of any variables.

The exact features provided are implementation-defined, but for portability a core set of features is given in Appendix B (Standard Feature Identifiers).