[plt-scheme] sicp exercise 2.23

From: Felix Klock's PLT scheme proxy (pltscheme at pnkfx.org)
Date: Wed Apr 30 08:25:23 EDT 2008

On Apr 29, 2008, at 11:35 PM, Benjamin L. Russell wrote:
> No, don't use "begin"!  One of the main points of this exercise is  
> to learn to use side-effects.
>
> Here is my solution and the results of a sample run:
>
> --
> (define nil '())
> ;Value: nil
>
> (define (for-each proc items)
>  (if (null? items)
>      nil
>      (for-each proc (for-each-helper proc items))))
> ;Value: for-each
>
> (define (for-each-helper proc items)
>  (if (null? (proc (car items)))
>      nil
>      (cdr items)))
> ;Value: for-each-helper

This seems broken; what if I pass in a proc argument that that returns  
the empty list when it is invoked?  Your helper will prematurely end  
the traversal of the list.

The following revision should work, but it is a bit odd for a reader:

(define (for-each-helper proc items)
   (if (proc (car items))
       (cdr items)
       (cdr items)))

But I'm not sure that the helper is really necessary.

If I had to handle any kind of value produced from the proc argument  
and I couldn't use begin, I would do something like:

(define (for-each proc items)
   (if (null? items)
       '()
       (and (or (proc (car items)) #t) (for-each proc (cdr items)))))

But I don't understand why I shouldn't use begin here, since that  
really *is* for appropriately ordering a series of side-effecting  
computations.

-Felix



Posted on the users mailing list.