Search code examples
schemesicp

Can the let block be trivially removed from this SICP chapter 3 code without anything changing?


Chapter 3 of SICP contains this unusual code block.

(define (propagate)
  (if (empty-agenda? the-agenda)
      'done
      (let ((first-item (first-agenda-item the-agenda)))
        (first-item)
        (remove-first-agenda-item! the-agenda)
        (propagate))))

To my eye, first-item is only used once here, so I don't see the need for the let. Is there any particular reason why the following code would not be equivalent?

(define (propagate)
  (if (empty-agenda? the-agenda)
      'done
      (begin
        (first-agenda-item the-agenda)
        (remove-first-agenda-item! the-agenda)
        (propagate))))

Solution

  • The idea of your transformation is perfectly fine, but you've done it incorrectly, as Shawn says in a comment.

    The simplest example of your error would be to turn code like this:

    (let ((f something))
      (f)
      x)
    

    into

    (begin
      something
      x)
    

    Note that the extra call to (f) has been missed here: the original version computes a function and then calls it, while the transformation computes a function but throws it away. A more accurate transformation would be:

    (begin
      (something)
      x)