'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 1:[1]

"The idea of a let block that is not doing variable assignment is strange to me."

but it does variable initialization, and variable reference. It could be have been written as

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

and what you've written is equivalent to

(define (propagate)
  (if (empty-agenda? the-agenda)
      'done
      (let ((first-item #f))
        (set! first-item (first-agenda-item the-agenda))
         first-item                              ; NB! _No_ _Parens_
        (remove-first-agenda-item! the-agenda)
        (propagate))))

Your line (first-agenda-item the-agenda) returns the first value in the-agenda but does not use it -- doesn't do anything with it.

But the original (first-item) refers to that value by name, first-item, and uses it i.e. calls that value as a function with no arguments.

Following the principle of substituting equals for equals, in a pure code (i.e. such that deals only with values, and not any places in computer memory), we replace the name in the pure subset of the code

                            ; impure: deals with a named place in computer memory
        (set! first-item (first-agenda-item the-agenda) )
                            ; pure: refers to a value by the name it was given
        (     first-item                                )

with its value

        (                (first-agenda-item the-agenda) )

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Will Ness