#
Chapter 2
Basic Syntax Extensions

## 2.1 Evaluation Order

In an application expression, the procedure expression and the argument expressions are always evaluated left-to-right. Similarly, expressions for `let` and `letrec` bindings are evaluated in sequence from left to right.

## 2.2 Multiple Return Values

MzScheme supports the R5RS ``values`` and ``call-with-values`` procedure, and also provides binding forms for multiple-value expressions, discussed in section 2.8.

Multiple return values are legal in MzScheme whenever the return value of an expression is ignored. For example, all but the last expression in a `begin` form can legally return multiple values in any context. If a built-in procedure takes a procedure argument, and the built-in procedure does not inspect the result of the supplied procedure, then the supplied procedure can return multiple values. For example, the procedure supplied to ``for-each`` can return any number of values, but the procedure supplied to ``map`` must return a single value.

When the number of values returned by an expression does not match the number of values expected by the expression's context, the `exn:fail:contract:arity` exception is raised (at run time).

Examples:

    (- (values 1)) ; => -1
    (- (values 1 2)) ; => error: returned 2 values to single-value context
    (- (values)) ; => error: returned 0 values to single-value context
    (call-with-values
      (lambda () (values 1 2))
      (lambda (x y) y)) ; => 2
    (call-with-values
      (lambda () (values 1 2))
      (lambda z z)) ; => (1 2)
    (call-with-values
      (lambda () (let/cc k (k 3 4)))
      (lambda (x y) y)) ; => 4
    (call-with-values
      (lambda () (values 'hello 1 2 3 4))
      (lambda (s . l)
        (format "~s = ~s" s l))) ; => "hello = (1 2 3 4)"

## 2.3 Cond and Case

The `else` and `=>` identifiers in a `cond` or `case` statement are handled specially only when they are not lexically bound or module-bound:

    (cond [1 => add1]) ; => 2
    (let ([=> 5]) (cond [1 => add1])) ; => #<primitive:add1>

## 2.4 When and Unless

The `when` and `unless` forms conditionally evaluate a single body of expressions:

- `(when test-expr expr `···`1)` evaluates the `expr` body expressions only when `test-expr` returns a true value.

- `(unless test-expr expr `···`1)` evaluates the `expr` body expressions only when `test-expr` returns `#f`.

The result of a `when` or `unless` expression is the result of the last body expression if the body is evaluated, or void (see section 3.1) if the body is not evaluated.

## 2.5 And and Or

In an `and` or `or` expression, the last test expression can return multiple values (see section 2.2). If the last expression is evaluated and it returns multiple values, then the result of the entire `and` or `or` expression is the multiple values. Other sub-expressions in an `and` or `or` expression must return a single value.

## 2.6 Sequences

The `begin0` form is like `begin`, but the value of the first expression in the form is returned instead of the value of the last expression:

    (let ([x 4])
      (begin0 x (set! x 9) (display x))) ; => displays 9 then returns 4

The first sub-expression in a `begin0` expression is in tail position if and only if it is the only sub-expression.

## 2.7 Quote and Quasiquote

The `quote` form never allocates, so that the result of multiple evaluations of a single `quote` expression are always ``eq?``. Nevertheless, a quoted cons cell, vector, or list is mutable; mutations to the result of a `quote` application are visible to future evaluations of the `quote` expression.

The `quasiquote` form allocates only as many fresh cons cells, vectors, and boxes as are needed without analyzing `unquote` and `unquote-splicing` expressions. For example, in

    `(,1 2 3)

a single reader-allocated tail `'(2 3)` is used for every evaluation of the `quasiquote` expression.

The standard Scheme `quasiquote` has been extended so that `unquote` and `unquote-splicing` work within immediate boxes:

    `#&(,(- 2 1) ,@(list 2 3)) ; => #&(1 2 3)

See section 11.2.4 for more information about immediate boxes.

MzScheme defines the `unquote` and `unquote-splicing` identifiers as top-level syntactic forms that always report a syntax error. The `quasiquote` form recognizes normal `unquote` and `unquote-splicing` uses via ``module-identifier=?``. (See section 12.3.1 for more information on identifier comparisons.)

## 2.8 Binding Forms

### 2.8.1 Definitions

A procedure definition

    (define variable (lambda formals expr ···1))

can be abbreviated

    (define (variable . formals) expr ···1)

In addition to this standard Scheme abbreviation, MzScheme supports an MIT-style generalization, so that a definition

    (define header (lambda formals expr ···1))

can be abbreviated

    (define (header . formals) expr ···1))

even if `header` is itself a parenthesized procedure abbreviation. The general syntax of `define` is as follows:

    (define variable expr)
    (define (header . formals) expr ···1)

    header is one of
      variable
      (header . formals)

    formals is one of
      variable
      (variable ···)
      (variable variable ··· . variable)

Multiple values can be bound to multiple variables at once using `define-values`:

    (define-values (variable ···) expr)

The number of values returned by `expr` must match the number of `variable`s provided, and the `variable`s must be distinct. No procedure-definition abbreviation is available for `define-values`.

Examples:

    (define x 1)
    x ; => 1
    (define (f x) (+ x 1))
    (f 2) ; => 3
    (define (((g x) y z) . w) (list x y z w))
    (let ([h ((g 1) 2 3)])
      (list (h 4 5) (h 6))) ; => '((1 2 3 (4 5)) (1 2 3 (6)))

    (define-values (x) 2)
    x ; => 2
    (define-values (x y) (values 3 4))
    x ; => 3
    y ; => 4
    (define-values (x y) (values 5 (add1 x)))
    y ; => 4
    (define-values () (values)) ; same as (void)
    (define x (values 7 8)) ;  => error: 2 values for 1-value context
    (define-values (x y) 7) ;  => error: 1 value for 2-value context
    (define-values () 7) ;  => error: 1 value for 0-value context

### 2.8.2 Local Bindings

Local variables are bound with standard Scheme's `let`, `let*`, and `letrec`. MzScheme's `letrec` form guarantees sequential left-to-right evaluation of the binding expressions. (The `letrec` bound in the result of `(scheme-report-environment `5`)`, however, is defined exactly as in R5RS.)

Multiple values are bound to multiple local variables at once with `let-values`, `let*-values`, and `letrec-values`. The syntax for `let-values` is:

    (let-values (((variable ···) expr) ···) body-expr ···1)

As in `define-values`, the number of values returned by each `expr` must match the number of `variable`s declared in the corresponding clause. Each `expr` remains outside of the scope of all variables bound by the `let-values` expression.

The syntax for `let*-values` and `letrec-values` is the same as for `let-values`, and the binding semantics for each form corresponds to the single-value binding form:

- In a `let*-values` expression, the scope of the variables of each clause includes all of the remaining binding clauses. The clause expressions are evaluated and bound to variables sequentially.

- In a `letrec-values` expression, the scope of the variables of each clause includes all of the binding clauses. The clause expressions are evaluated and bound to variables sequentially.

When a `letrec` or `letrec-values` expression is evaluated, each variable binding is initially assigned the special undefined value (see section 3.1); the undefined value is replaced after the corresponding expression is evaluated.

Examples:

    (define x 0)
    (let ([x 5] [y x]) y) ; => 0
    (let* ([x 5] [y x]) y) ; => 5
    (letrec ([x 5] [y x]) y) ; => 5
    (letrec ([x y] [y 5]) x) ; => undefined
    (let-values ([(x) 5] [(y) x]) y) ; => 0
    (let-values ([(x y) (values 5 x)]) y) ; => 0
    (let*-values ([(x) 5] [(y) x]) y) ; => 5
    (let*-values ([(x y) (values 5 x)]) y) ; => 0
    (letrec-values ([(x) 5] [(y) x]) y) ; => 5
    (letrec-values ([(x y) (values 5 x)]) y) ; => undefined
    (letrec-values ([(odd even) (values
                                 (lambda (n) (if (zero? n) #f (even (sub1 n))))
                                 (lambda (n) (if (zero? n) #t (odd (sub1 n)))))])
       (odd 17)) ; => #t

### 2.8.3 Assignments

The standard `set!` form assigns a value to a single global, local, or module variable. Multiple variables can be assigned at once using `set!-values`:

    (set!-values (variable ···) expr)

The number of values returned by `expr` must match the number of `variable`s provided.

The `variable`s, which must be distinct, can be any mixture of global, local, and module variables. Assignments are performed sequentially from the first `variable` to the last. If an error occurs in one of the assignments (perhaps because a global variable is not yet bound), then the assignments for the preceding `variable`s will have already completed, but assignments for the remaining `variable`s will never complete.

### 2.8.4 Fluid-Let

The syntax for a `fluid-let` expression is the same as for `let`:

    (fluid-let ((variable expr) ···) body-expr ···1)

Each `variable` must be either a local variable or a global or module variable that is bound before the `fluid-let` expression is evaluated. Before the `body-expr`s are evaluated, the bindings for the `variable`s are `set!` to the values of the corresponding `expr`s. Once the `body-expr`s have been evaluated, the values of the variables are restored. The value of the entire `fluid-let` expression is the value of the last `body-expr`.

### 2.8.5 Syntax Expansion and Internal Definitions

All binding forms are syntax-expanded into `define-values`, `let-values`, `letrec-values`, `define-syntaxes`, and `letrec-syntaxes+values` expressions. The `set!-values` form is expanded to `let-values` with `set!`. See section 12.6.1 for more information.

All `define-values` expressions that are inside only `begin` expressions are treated as top-level definitions. Body `define-values` expressions in a `module` expression are handled specially as described in section 5.1. Any other `define-values` expression is either an internal definition or syntactically illegal. The same is true of `define-syntaxes` expressions.

Internal definitions can appear at the start of a sequence of expressions, such as the start of a `lambda`, `case-lambda`, or `let` body. At least one non-definition expression must follow a sequence of internal definitions. The first expression in a `begin0` expression cannot be an internal definition; for the purposes of internal definitions, the second expression is the start of the sequence.

When a `begin` expression appears within a sequence, its content is inlined into the sequence (recursively, if the `begin` expression contains other `begin` expressions). Like top-level `begin` expressions (and unlike other `begin` expressions), a `begin` expression within an internal definition sequence can be empty.

An internal `define-values` or `define-syntaxes` expression is transformed, along with the expressions following it, into a `letrec-syntaxes+values` expression: the identifiers bound by the internal definitions become the binding identifiers of the new `letrec-syntaxes+values` expression, and the expressions that follow the definitions become the body of the new `letrec-syntaxes+values` expression.

Multiple adjacent definitions are collected into a single `letrec-syntaxes+values` transformation, so that the definitions can be mutually recursive, but the definitions expressions must be adjacent. A non-definition marks the start of a sequence of expressions to be moved into the body of the newly created `letrec-syntaxes+values` form.

Internal definitions are detected after a partial syntax expansion that stops at core forms, and thus exposes `begin`, `define-values`, and `define-syntaxes`. Forms are expanded left to right, and whenever a definition is discovered, a binding is introduced immediately for further expansion, so a definition can shadow variables when later forms are expanded. Furthermore, when a `define-syntaxes` form is discovered, the right-hand side is immediately evaluated, and the result is bound as syntax to the corresponding identifier(s); thus, a locally defined macro can be used to generate later definitions in the same internal-definition context.

## 2.9 Case-Lambda

The `case-lambda` form creates a procedure that dispatches to a particular body of expressions based on the number of arguments that the procedure receives. The `case-lambda` form provides a mechanism for creating variable-arity procedures with more control and efficiency than using a `lambda` ``rest argument,'' such as the `x` in `(lambda (a . x) expr `···`1)`.

A `case-lambda` expression has the form:

    (case-lambda
      (formals expr ···1)
      ···)

    formals is one of
      variable
      (variable ···)
      (variable ··· . variable)

Each `(formals expr `···`1)` clause of a `case-lambda` expression is analogous to a `lambda` expression of the form `(lambda formals expr `···`1)`. The scope of the `variable`s in each clause's `formals` includes only the same clause's `expr`s. The `formals` variables are bound to actual arguments in an application in the same way that `lambda` variables are bound in an application.

When a `case-lambda` procedure is invoked, one clause is selected and its `expr`s are evaluated for the application; the result of the last `expr` in the clause is the result of the application. The clause that is selected for an application is the first one with a `formals` specification that can accommodate the number of arguments in the application.3

Examples:

    (define f
      (case-lambda
        [(x) x]
        [(x y) (+ x y)]
        [(a . any) a]))
    (f 1) ; => 1
    (f 1 2) ; => 3
    (f 4 5 6 7) ; => 4
    (f) ; => raises exn:fail:contract:arity

The result of a `case-lambda` expression is a procedure, just like the result of a `lambda` expression. Thus, the `procedure?` predicate returns `#t` when applied to the result of a `case-lambda` expression.

## 2.10 Procedure Application

The ``empty application'' form `()` expands to the quoted empty list `'()`.

## 2.11 Variable Reference

The `#%variable-reference` form returns a value representing the address of a top-level or module variable:

    (#%variable-reference variable)
    (#%variable-reference (#%top . variable))

In the non-`#%top` form, a syntax error is reported if `variable` is not bound to a top-level or module variable.

The result of a `#%variable-reference` expression is opaque, with no useful operation in MzScheme. See Inside PLT MzScheme for information on its use in low-level extensions to MzScheme.

3 It is possible that a clause in a `case-lambda` expression can never be evaluated because a preceding clause always matches the arguments.