A definition of for-each
No. Your function needs to handle the empty list too. If your implementation supports unless, use this:

(define (for-each f l)
  (unless (null? l)
    (f (car l))
    (for-each f (cdr l))))


Otherwise, the R5RS-compatible version would be:

(define (for-each f l)
  (cond ((not (null? l))
         (f (car l))
         (for-each f (cdr l)))))


Granted, the implicit begin behaviour of cond is not explained until Chapter 3. So if you want to avoid using that, here's a similar version that uses let to simulate begin:

(define (for-each f l)
  (cond ((not (null? l))
         (let ()
           (f (car l))
           (for-each f (cdr l))))))


Now, here, too, the let body is an implicit begin. If you want to work around that, too, then bind the result of the side-effect to a dummy variable:

(define (for-each f l)
  (cond ((not (null? l))
         (let ((unused (f (car l))))
           (for-each f (cdr l))))))