[41] derived-expression = *cond-expression*
| *case-expression*
| *and-expression*
| *or-expression*
| *binding-expression*
| *named-let*
| *quasiquotation*

[42] cond-expression = (cond
*cond-clause*+)
| (cond
*cond-clause**
(else *expression*))

[43] cond-clause = (*test* *expression*)
| (*test*)
| (*test* => *recipient*)

[44] recipient = *expression*

A *cond-expression* is evaluated by evaluating the *test*
expressions of each successive *cond-clause* in order until one of them
evaluates to a true value. When a *test* evaluates to a true
value, then the result of evaluating the *expression* in the
*cond-clause* is returned as the result of the entire cond
expression. If the selected *cond-clause* contains only the
*test* and no *expression*, then the value of the
*test* is returned as the result.
If the *cond-clause* contains a *recipient*,
then *recipient* is evaluated.
Its value shall be a procedure of one
argument; this procedure is then invoked on the value of the
*test*.
If all *test*s evaluate
to false values, and there is no else clause, then an error is signaled;
if there is an else clause,
then the result of evaluating its *expression*
is returned.

(cond ((> 3 2) 'greater)

((< 3 2) 'less)) greater

(cond ((> 3 3) 'greater)

((< 3 3) 'less)

(else 'equal)) equal

((< 3 2) 'less)) greater

(cond ((> 3 3) 'greater)

((< 3 3) 'less)

(else 'equal)) equal

[45] case-expression = (case
*key*
*case-clause*+)
| (case
*key*
*case-clause**
(else *expression*))

[46] key = *expression*

[47] case-clause = ((*datum**) *expression*)

All the *datum*s shall be distinct.
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 equal (in the sense of
equal?) to a *datum*, then the
result of evaluating the *expression*
in the corresponding *case-clause* is
returned as the result of the *case-expression*. If the result of
evaluating *key* is different from every *datum*, and if
there is an else clause, then the result of evaluating its expression
is the result of the *case-expression*; otherwise,
an error is signaled.

(case (* 2 3)

((2 3 5 7) 'prime)

((1 4 6 8 9) 'composite)) composite

(case (car '(c d))

((a e i o u) 'vowel)

((w y) 'semivowel)

(else 'consonant)) consonant

((2 3 5 7) 'prime)

((1 4 6 8 9) 'composite)) composite

(case (car '(c d))

((a e i o u) 'vowel)

((w y) 'semivowel)

(else 'consonant)) consonant

[48] and-expression = (and *test**)

The *test* expressions are evaluated from left to right, and the
value of the first expression that evaluates to a false value
is returned. Any remaining expressions
are not evaluated. If all the expressions evaluate to true values, the
value of the last expression is 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 'c '(f g)) (f g)

(and) #t

(and (= 2 2) (< 2 1)) #f

(and 1 2 'c '(f g)) (f g)

(and) #t

[49] or-expression = (or *test**)

The *test* expressions are evaluated from left to right, and the value of the
first expression that evaluates to a true value
is returned. Any remaining expressions
are not evaluated. If all expressions evaluate to false values, the
value of the last expression is returned. 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 (= 2 2) (< 2 1)) #t

(or #f #f #f) #f

[50] binding-expression = *let-expression*
| *let*-expression*
| *letrec-expression*

The three binding constructs let, let*, and letrec
give the expression language a block structure, like Algol 60. The syntax of the three
constructs is identical, but they differ in the regions they establish
for their variable bindings. In a let expression, the initial
values are computed before any of the variables become bound; in a
let* expression, the bindings and evaluations are performed
sequentially; while in a letrec expression, all the bindings are in
effect while their initial values are being computed, thus allowing
mutually recursive definitions.

[51] let-expression = (let *bindings* *body*)

[52] bindings = (*binding-spec**)

[53] binding-spec = (*variable* *init*)

[54] init = *expression*

(let ((x 2) (y 3))

(* x y)) 6

(let ((x 2) (y 3))

(let ((x 7)

(z (+ x y)))

(* z x))) 35

(* x y)) 6

(let ((x 2) (y 3))

(let ((x 7)

(z (+ x y)))

(* z x))) 35

[55] let*-expression = (let* *bindings* *body*)

(let ((x 2) (y 3))

(let* ((x 7)

(z (+ x y)))

(* z x))) 70

(let* ((x 7)

(z (+ x y)))

(* z x))) 70

[56] letrec-expression = (letrec *bindings* *body*)

(letrec ((even?

(lambda (n)

(if (zero? n)

#t

(odd? (- n 1)))))

(odd?

(lambda (n)

(if (zero? n)

#f

(even? (- n 1))))))

(even? 88))

#t

(lambda (n)

(if (zero? n)

#t

(odd? (- n 1)))))

(odd?

(lambda (n)

(if (zero? n)

#f

(even? (- n 1))))))

(even? 88))

#t

[57] named-let = (let
*variable*
(*binding-spec**)
*body*)

Named let has the same syntax and semantics as ordinary let
except that *variable* is bound within *body* to a procedure
whose formal arguments are the bound variables and whose body is
*body*. Thus, the execution of *body* may be repeated by
invoking the procedure named by *variable*.

(let loop ((numbers '(3 -2 1 6 -5))

(nonneg '())

(neg '()))

(cond ((null? numbers) (list nonneg neg))

((>= (car numbers) 0)

(loop (cdr numbers)

(cons (car numbers) nonneg)

neg))

((< (car numbers) 0)

(loop (cdr numbers)

nonneg

(cons (car numbers) neg)))))

((6 1 3) (-5 -2))

(nonneg '())

(neg '()))

(cond ((null? numbers) (list nonneg neg))

((>= (car numbers) 0)

(loop (cdr numbers)

(cons (car numbers) nonneg)

neg))

((< (car numbers) 0)

(loop (cdr numbers)

nonneg

(cons (car numbers) neg)))))

((6 1 3) (-5 -2))

The following grammar for quasiquote expressions is not context-free.
It is presented as a recipe for generating an infinite number of
production rules. Imagine a copy of the following rules for D = 1, 2,
3, . D keeps track of the nesting depth.

[58] quasiquotation = *quasiquotation_1*

[59] template_0 = *expression*

[60] quasiquotation_D = &grave.*template_D*
| (quasiquote *template_D*)

[61] template_D = *simple-datum*
| *list-template_D*
| *unquotation_D*

[62] list-template_D = (*template-or-splice_D**)
| (*template-or-splice_D*+ . *template_D*)
| '*template_D*
| *quasiquotation_D+1*

[63] unquotation_D = ,*template_D-1*
| (unquote *template_D-1*)

[64] template-or-splice_D = *template_D*
| *splicing-unquotation_D*

[65] splicing-unquotation_D = ,*template_D-1*
| (unquote-splicing *template_D-1*)

&grave.(list ,(+ 1 2) 4) (list 3 4)

(let ((name 'a)) &grave.(list ,name ',name))

(list a (quote a))

&grave.(a ,(+ 1 2) ,(map abs '(4 -5 6)) b)

(a 3 4 5 6 b)

&grave.((foo ,(- 10 3)) ,(cdr '(c)) . ,(car '(cons)))

((foo 7) . cons)

(let ((name 'a)) &grave.(list ,name ',name))

(list a (quote a))

&grave.(a ,(+ 1 2) ,(map abs '(4 -5 6)) b)

(a 3 4 5 6 b)

&grave.((foo ,(- 10 3)) ,(cdr '(c)) . ,(car '(cons)))

((foo 7) . cons)

&grave.(a &grave.(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)

(a &grave.(b ,(+ 1 2) ,(foo 4 d) e) f)

(let ((name1 'x)

(name2 'y))

&grave.(a &grave.(b ,,name1 ,',name2 d) e))

(a &grave.(b ,x ,'y d) e)

(a &grave.(b ,(+ 1 2) ,(foo 4 d) e) f)

(let ((name1 'x)

(name2 'y))

&grave.(a &grave.(b ,,name1 ,',name2 d) e))

(a &grave.(b ,x ,'y d) e)

(quasiquote (list (unquote (+ 1 2)) 4)) (list 3 4)

'(quasiquote (list (unquote (+ 1 2)) 4))

&grave.(list ,(+ 1 2) 4) i.e., (quasiquote (list (unquote (+ 1 2)) 4))

'(quasiquote (list (unquote (+ 1 2)) 4))

&grave.(list ,(+ 1 2) 4) i.e., (quasiquote (list (unquote (+ 1 2)) 4))