,
I decided to whip up a quick Scheme version of Cook's
experiment. He mentioned some implementation issues
involving the sizes of integers and floating-point numbers
in Python, and I wondered how well Scheme would fare.
For my first attempt, I did the simplest thing that would
possibly work. I already had a tail-recursive
`factorial` function and so wrote a procedure that
would call it *n* times and record the first digit
of each:
(define benford-factorials
(lambda (n)
(let ((counts (make-vector 10 0)))
(letrec ((foreach
(lambda (n)
(if (zero? n)
counts
(let ((lead-digit (first-digit (factorial n))))
(vector-set! counts lead-digit
(+ 1 (vector-ref counts lead-digit)))
(foreach (- n 1)))))))
(foreach n)))))

This gets the answers for us:
> (benford-factorials 500)
#(0 148 93 67 38 34 43 24 28 25)

Of course, it is wildly inefficient. My naive implementation
computes and acts on each factorial independently, which means
that it recomputes (*n*-1)!, (*n*-2)!, ... for each
value less than *n*. As a result, `benford-factorials`
becomes unnecessarily sluggish for even relatively small values
of *n*. How can I do better?
I decided to create a new factorial function, one that caches
the smaller factorials it creates on the way to *n*!. I
call it `all-factorials-up-to`:
(define all-factorials-up-to
(lambda (n)
(letrec ((aps (lambda (i acc)
(if (> i n)
acc
(aps (+ i 1)
(cons (* i (car acc)) acc))))))
(aps 2 '(1)))))

Now, `benford-factorials` can use a more functional
approach: map `first-digit` over the list of factorials,
and then map a count incrementer over the list of first digits.
(define benford-factorials
(lambda (n)
(let ((counts (make-vector 10 0))
(first-digits (map first-digit
(all-factorials-up-to n))))
(map (lambda (digit)
(vector-set! counts digit
(+ 1 (vector-ref counts digit))))
first-digits)
counts)))

(We can, of course, do without the temporary variable
`first-digit` by dropping the first `map`
right into the second. I often create