0

The seasoned schemer on page 78 has the below definition of leftmost and lm.

(define leftmost
  (lambda (l)
    (letcc skip
      (lm l skip))))

(define lm
  (lambda (l out)
    (cond
      ((null? l) (quote ()))
      ((atom? (car l)) (out (car l)))
      (else (let ()
              (lm (car l) out)
              (lm (cdr l) out))))))

On the next page it has the following explanation of having multiple expressions in the value part. I don't understand the explanation of how it makes leftmost work on, for example (() a).

When a (let ...) has two expressions in its value part, we must first determine the value of the first expression. If it has one, we ignore it and determine the value of the second expression."

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
user782220
  • 10,677
  • 21
  • 72
  • 135
  • 1
    @LittleBobbyTables there are _several_ tags for specific books, for example: sicp, the-little-schemer, clrs, etc. This is specially useful for books about learning how to program, people need to refer to the specific book in their questions, so please don't go deleting a newly created tag for a book just because you don't agree with it, other people might find it useful – Óscar López Nov 13 '13 at 15:30

1 Answers1

1

The key to this is that out in this case is a continuation. Continuations, unlike procedures, do not return once invoked.

So, the two expressions in let are executed sequentially: first, (lm (car l) out), then (lm (cdr l) out). Because out is a continuation, and it's invoked when an atom is encountered, the (lm (car l) out) will not return if an atom is encountered in the (car l). So the (lm (cdr l) out) will only happen if there are no atoms in (car l)---which is the case for your example of (() a).

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • So on the example `(() a)` it will recurse doing `(lm (car l) out)` which evaluates to `(quote ())` and since that is not an atom evaluation will move on to `(lm (cdr l) out)`. But where in the book is it explained that a `let` expression with multiple value will evaluate them sequentially until it hits the first atom? – user782220 Nov 13 '13 at 23:29
  • @user782220 If a `let` body has multiple expressions, each one will be executed in sequence; it doesn't care about whether it hits an atom or not. The magic is that `(lm (car l) out)` could potentially call `out` (via `(out (car l))`), which is a continuation. That's what makes it "break out" and not continue on with `(lm (cdr l) out)`. – C. K. Young Nov 13 '13 at 23:35