Primitive expression syntax

expression ::= literal-expression | variable-reference
  | procedure-call | TODO

Literal expressions

literal-expression ::= (quote datum)
  |  datum
  | constant 
constant ::= number | boolean | character | string

(quote datum) evaluates to datum, which may be any external representation of a Scheme object. This notation is used to include literal constants in Scheme code.

(quote a)               ⇒  a 
(quote #(a b c))        ⇒  #(a b c)
(quote (+ 1 2))         ⇒  (+ 1 2)

(quote datum) may be abbreviated as 'datum. The two notations are equivalent in all respects.

’a                      ⇒  a
’#(a b c)               ⇒  #(a b c)
’()                     ⇒  ()
’(+ 1 2)                ⇒  (+ 1 2)
’(quote a)              ⇒  (quote a)
’’a                     ⇒  (quote a)

Numerical constants, string constants, character constants, bytevector constants, and boolean constants evaluate to themselves; they need not be quoted.

145932          ⇒  145932
#t              ⇒  #t
"abc"           ⇒  "abc"

Variable references

variable-reference ::= identifier

An expression consisting of a variable is a variable reference if it is not a macro use (see below). The value of the variable reference is the value stored in the location to which the variable is bound. It is a syntax violation to reference an unbound variable.

The following example examples assumes the base library has been imported:

(define x 28)
x   ⇒  28

Procedure calls

procedure-call ::= (operator operand …)
operator ::= expression
operand ::= expression

A procedure call consists of expressions for the procedure to be called and the arguments to be passed to it, with enclosing parentheses. A form in an expression context is a procedure call if operator is not an identifier bound as a syntactic keyword.

When a procedure call is evaluated, the operator and operand expressions are evaluated (in an unspecified order) and the resulting procedure is passed the resulting arguments.

(+ 3 4)                ⇒  7
((if #f + *) 3 4)      ⇒  12

Macros

Libraries and top–level programs can define and use new kinds of derived expressions and definitions called syntactic abstractions or macros. A syntactic abstraction is created by binding a keyword to a macro transformer or, simply, transformer.

The transformer determines how a use of the macro (called a macro use) is transcribed into a more primitive form.

Most macro uses have the form:

(keyword datum …)

where keyword is an identifier that uniquely determines the kind of form. This identifier is called the syntactic keyword, or simply keyword. The number of datums and the syntax of each depends on the syntactic abstraction.

Macro uses can also take the form of improper lists, singleton identifiers, or set! forms, where the second subform of the set! is the keyword:

(keyword datum … . datum)
keyword
(set! keyword datum)

The define-syntax, let-syntax and letrec-syntax forms create bindings for keywords, associate them with macro transformers, and control the scope within which they are visible.

The syntax-rules and identifier-syntax forms create transformers via a pattern language. Moreover, the syntax-case form allows creating transformers via arbitrary Scheme code.

Keywords occupy the same name space as variables. That is, within the same scope, an identifier can be bound as a variable or keyword, or neither, but not both, and local bindings of either kind may shadow other bindings of either kind.

Macros defined using syntax-rules and identifier-syntax are “hygienic” and “referentially transparent” and thus preserve Scheme’s lexical scoping.

  • If a macro transformer inserts a binding for an identifier (variable or keyword) not appearing in the macro use, the identifier is in effect renamed throughout its scope to avoid conflicts with other identifiers.

  • If a macro transformer inserts a free reference to an identifier, the reference refers to the binding that was visible where the transformer was specified, regardless of any local bindings that may surround the use of the macro.

Macros defined using the syntax-case facility are also hygienic unless datum->syntax is used.