Next: , Up: Control Mechanisms   [Contents][Index]


6.13.1 Sequencing and Splicing

As an expression, the begin syntax is used to evaluate a sequence of sub-expressions in order. Consider the conditional expression below:

(if (> x 0)
    (begin (display "greater") (newline)))

If the test is true, we want to display “greater” to the current output port, then display a newline. We use begin to form a compound expression out of this sequence of sub-expressions.

syntax: begin expr …

The expression(s) are evaluated in left-to-right order and the value of the last expression is returned as the value of the begin-expression. This expression type is used when the expressions before the last one are evaluated for their side effects.

The begin syntax has another role in definition context (see Internal Definitions). A begin form in a definition context splices its subforms into its place. For example, consider the following procedure:

(define (make-seal)
  (define-sealant seal open)
  (values seal open))

Let us assume the existence of a define-sealant macro that expands out to some definitions wrapped in a begin, like so:

(define (make-seal)
  (begin
    (define seal-tag
      (list 'seal))
    (define (seal x)
      (cons seal-tag x))
    (define (sealed? x)
      (and (pair? x) (eq? (car x) seal-tag)))
    (define (open x)
      (if (sealed? x)
          (cdr x)
          (error "Expected a sealed value:" x))))
  (values seal open))

Here, because the begin is in definition context, its subforms are spliced into the place of the begin. This allows the definitions created by the macro to be visible to the following expression, the values form.

It is a fine point, but splicing and sequencing are different. It can make sense to splice zero forms, because it can make sense to have zero internal definitions before the expressions in a procedure or lexical binding form. However it does not make sense to have a sequence of zero expressions, because in that case it would not be clear what the value of the sequence would be, because in a sequence of zero expressions, there can be no last value. Sequencing zero expressions is an error.

It would be more elegant in some ways to eliminate splicing from the Scheme language, and without macros (see Macros), that would be a good idea. But it is useful to be able to write macros that expand out to multiple definitions, as in define-sealant above, so Scheme abuses the begin form for these two tasks.


Next: , Up: Control Mechanisms   [Contents][Index]