Notes on problem 6-14

  1. This problem really belongs in chapter 7, in my opinion, because the let special form (in chapter 7) makes it easier.
  2. Consider using this code when you solve 6.14. Note that the symbols defined within the lets refer to the unit of time that will be reported if the input to describe-time is less than the value indicated. In other words, if the input to describe-time is 90, you want to report (1.5 minutes). 90 is more than the value of the seconds variable, but less than the value of the minutes variable; think about how to use that in a cond.
(define (describe-time seconds)  ; input is in seconds
  (let ((seconds-per-minute 60))
    (let ((seconds-per-hour (* seconds-per-minute 60)))
      (let ((seconds-per-day (* seconds-per-hour 24)))
        (let ((seconds-per-year (* seconds-per-day 365.25))) ;; rough estimate
          (let ((seconds-per-century (* seconds-per-year 100)))
            (cond YOUR-CODE-HERE)

Your solution should cover seconds, minutes, days, hours, years, and centuries. If you want to include other measures of time, be my guest, but it is not necessary.

Now, you may be thinking to yourself, this looks disgusting. If we have hate nested ifs to the point of wanted cond, why do we need all of these lets? It turns out that Scheme has a special form, let*, that addresses this issue nicely:

(define (describe-time seconds)  ; input is in seconds
  (let* ((seconds-per-minute 60)
         (seconds-per-hour (* seconds-per-minute 60))
         (seconds-per-day (* seconds-per-hour 24))
         (seconds-per-year (* seconds-per-day 365.25))
         (seconds-per-century (* seconds-per-year 100)))
    (cond YOUR-CODE-HERE)

This is arguably much nicer. The variables in a let* come into scope immediately as opposed to requiring a closing parenthesis in let.