Question

I am new to Scheme and I am trying to familiarize myself with the language by reading Structure and Interpretation of Computer Programs. I am a bit confused about sequencing.

First, I understand that begin keyword is introduced to allow sequencing, needed so that manipulation over mutable structures is easier. What I don't understand is that sometimes they use sequencing as follows (motivated by example on page 268 of SCIP):

(define (stuff-0)
   (+ 1 2)
   (+ 1 3)
   'ok)

while the same can be implemented using begin:

(define (stuff-1)
  (begin
    (+ 1 2)
    (+ 1 3)
    'ok))

Is there a semantic difference between those two or the first one is just a syntactic sugar for the second?

Second, aside from practical importance, do we theoretically need the begin construct? I imagine for each sequence we need we could write a cascade of procedures that implement the sequence. It is impractical of course, but I am just interested in expressiveness of the language without the begin construct.

Was it helpful?

Solution

It's simple: inside a procedure, there's always an implicit begin. So this:

(define (f x)
  (begin
    <expression 1>
    <expression 2>
    <returned value>))

... Is completely equivalent to this:

(define (f x)
  <expression 1>
  <expression 2>
  <returned value>)

And no, there isn't any semantic difference, the second form above is just syntactic sugar for the first form. And the begin form is necessary, because there has to be a way to perform a sequence of expressions just for their effect in the specified order. Remember: in a begin (or for that matter, inside a procedure - it's the same) all the expressions get executed in the order they appear, their resulting values being essentially ignored, and only the last expression's value is returned at the end.

OTHER TIPS

Every define special from contains an implicit begin clause.

To the neophyte the second example is clearer, but to the experienced it is just noise.

One place you'll need a begin construct often is as the then or else clause of an if statement. You also need it in within anonymous functions.

An explicit begin is not needed. If you need to sequence something, but don't have begin, then you do this:

((lambda () <body1> <body2> ...))

The above is, in fact, exactly how you would implement begin as a macro. Here is the syntactic definition from R7RS:

 (define-syntax begin
    (syntax-rules ()
      ((begin exp ...)
       ((lambda () exp ...)))))

So your statement "I understand that begin keyword is introduced to allow sequencing" isn't really correct. begin is introduced as syntactic sugar on the fundamental sequencing construct of lambda.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top