8.3.1 Primitive Expression Types
[17] primitive-expression = variable-reference
| literal
| procedure-call
| lambda-expression
| conditional
8.3.1.1 Variable Reference
[18] variable-reference = variable
An expression consisting of a variable is a variable reference.
The value of the variable reference is the value to which the
variable is bound. It shall be an error to reference an unbound
variable.
[19] variable = identifier
[20] syntactic-keyword = expression-keyword
|
else
|
=>
|
define
[21] expression-keyword =
quote
|
lambda
|
if
|
cond
|
and
|
or
|
case
|
let
|
let*
|
letrec
|
quasiquote
|
unquote
|
unquote-splicing
Any identifier that is not a syntactic-keyword may be used as a
variable.
DSSSL languages may reserve identifiers as syntactic-keywords
in addition to those listed above.
8.3.1.2 Literals
[22] literal = quotation | self-evaluating
[23] quotation =
'
datum
|
(
quote
datum
)
(quote datum)
evaluates to datum.
[24] datum = simple-datum
| list
[25] simple-datum = boolean
| number
| character
| string
| symbol
| keyword
| named-constant
| glyph-identifier
datum
may be any external representation of an expression language object.
This notation is used to include literal
constants in expressions.
A
glyph-identifier is allowed only within a
style-language-body.
(quote a) a
(quote (+ 1 2)) (+ 1 2)
(quote datum)
may be abbreviated as
'
datum. The two notations are equivalent in all
respects.
'a a
'() ()
'(+ 1 2) (+ 1 2)
'(quote a) (quote a)
''a (quote a)
[26] self-evaluating = boolean
| number
| character
| string
| keyword
| named-constant
| glyph-identifier
Boolean constants, numerical constants, character constants,
string constants, keywords,named constants, and glyph identifiers
evaluate to themselves; they need not be quoted.
'"abc" "abc"
"abc" "abc"
'145932 145932
145932 145932
'#t #t
#t #t
abc: abc:
'abc: abc:
8.3.1.3 Procedure Call
[27] procedure-call =
(
operator operand*
)
[28] operator = expression
[29] operand = expression
A procedure call is written by simply enclosing in parentheses
expressions for the procedure to be called and the arguments to be
passed to it. The operator and operand expressions are evaluated,
and the resulting procedure is passed the resulting
arguments.
(+ 3 4) 7
((if #f + *) 3 4) 12
If more than one of the operator or operand expressions signals an
error, it is system-dependent which of the errors will be reported to
the user.
A number of procedures are available as the values of variables in the
initial environment; for example, the addition and multiplication
procedures in the above examples are the values of the variables +
and *. New procedures are created by evaluating lambda expressions.
Procedure calls are also called
combinations.
NOTE 7
In contrast to other dialects of Lisp, the operator expression
and the operand
expressions are always evaluated with the same evaluation rules.
8.3.1.4 Lambda Expression
[30] lambda-expression =
(
lambda
(
formal-argument-list
)
body
)
A lambda expression evaluates to a procedure. The environment in
effect when the lambda expression was evaluated is remembered as part of the
procedure. When the procedure is later called with some actual
arguments, the environment in which the lambda expression was evaluated shall
be extended by binding the variables in the formal argument list to
the corresponding actual argument values,
and the body of the lambda expression
shall be evaluated in the extended environment. The result
of the body shall be returned as the result of the procedure call.
(lambda (x) (+ x x)) a procedure
((lambda (x) (+ x x)) 4) 8
(define reverse-subtract
(lambda (x y) (- y x)))
(reverse-subtract 7 10) 3
(define add4
(let ((x 4))
(lambda (y) (+ x y))))
(add4 6) 10
[31] formal-argument-list = required-formal-argument*
(
#!optional
optional-formal-argument*)?
(
#!rest
rest-formal-argument)?
(
#!key
keyword-formal-argument*)?
[32] required-formal-argument = variable
[33] optional-formal-argument = variable | (
(
variable initializer
)
)
[34] rest-formal-argument = variable
[35] keyword-formal-argument = variable | (
(
variable initializer
)
)
[36] initializer = expression
When the procedure is applied to a list of actual arguments,
the formal and actual arguments are processed from left to right
as follows:
- Variables in required-formal-arguments are bound to
successive actual arguments starting with the first actual argument.
It shall be an error if there are fewer actual arguments than
required-formal-arguments.
- Next variables in optional-formal-arguments are bound to
remaining actual arguments.
If there are fewer remaining actual arguments than
optional-formal-arguments, then the variables are bound
to the result of evaluating initializer, if one was specified,
and otherwise to #f.
The initializer is evaluated in an environment in which
all previous formal arguments have been bound.
- If there is a rest-formal-argument, then it is bound to a list of
all remaining actual arguments. These remaining actual arguments are
also eligible to be bound to keyword-formal-arguments.
If there is no rest-formal-argument and there are no
keyword-formal-arguments, then it shall be an error if there
are any remaining actual arguments.
- If
#!key
was specified in the formal-argument-list, there shall be an even number of remaining
actual arguments. These are interpreted as a series of pairs, where
the first member of each pair is a keyword
specifying the argument name, and the second is
the corresponding value. It shall be an error if the first member of a
pair
is not a keyword. It shall be an error if the argument name is not the
same
as a variable in a keyword-formal-argument, unless there is a
rest-formal-argument.
If the same argument name occurs more than once in the list
of actual arguments, then the first value is used.
If there is no actual argument for a particular keyword-formal-argument,
then the variable is bound to the result of evaluating initializer
if one was specified, and otherwise to #f.
The initializer is evaluated in an environment in which
all previous formal arguments have been bound.
NOTE 8
Use of
#!key
in a formal-argument-list in
the transformation language or style language requires the
keyword
feature.
It shall be an error for a
variable to appear more than once in a
formal-argument-list.
((lambda x x) 3 4 5 6) (3 4 5 6)
((lambda (x y #!rest z) z)
3 4 5 6) (5 6)
((lambda (x y #!optional z #!rest r #!key i (j 1)) (list x y z i: i j: j))
3 4 5 i: 6 i: 7) (3 4 5 i: 6 j: 1)
8.3.1.5 Conditional Expression
[37] conditional =
(
if
test
consequent
alternate
)
[38] test = expression
[39] consequent = expression
[40] alternate = expression
A
conditional is evaluated as follows: first,
test is evaluated. If it yields a true value,
then
consequent is evaluated and
its value is returned. Otherwise,
alternate is evaluated and its
value is returned.
(if (> 3 2) 'yes 'no) yes
(if (> 2 3) 'yes 'no) no
(if (> 3 2)
(- 3 2)
(+ 3 2)) 1