[plt-scheme] sicp exercise 2.23

From: Jos Koot (jos.koot at telefonica.net)
Date: Tue Apr 29 04:03:19 EDT 2008

Scheme allows more than one expr after the test in a cond clause::
(cond (test expr ... expr) ...)
You can't do this with 'if'.
(if test then-expr else-expr) does what it says.
It is *not* (if test then-expr andthen-expr andthen-expr).
It could have been (alternative-if test (then andthen andthen ...) (else 
and-else and-else ....)), but that's not the way it is.
The above form of cond has not yet been introduced either before reaching 
problem 2.23. Look at how you would implement map, then decide what to 
discard. An alternative is to make your own (somewhat restricted form of) 
begin but I doubt that that is the intention of the authors. There are 
several ways to make your own begin, for example with lambda or by using a 
helper procedure (in fact lambda too) If you are up to it, this may be 
instructive. You can do it with the restricted form of (lambda (arg ...) 
expr), i.e. only one expr for the body. Scheme allows (lambda (arg ...) expr 
... expr), but if I remember correctly, the latter form has not been 
introduced either before reaching 2.23. There are more ways to make your own 
begin, but lambda is by far the most elegant and simplest one. You have hit 
an essential point: evaluation for side effect.

----- Original Message ----- 
From: "Jason Wang" <randomtalk at gmail.com>
To: "PLT Scheme List" <plt-scheme at list.cs.brown.edu>
Sent: Tuesday, April 29, 2008 8:04 AM
Subject: [plt-scheme] sicp exercise 2.23

> Hey guys, i was just working through SICP book after having (pretty
> much) completed HtDP in school. I have  a question about 2.23 exercise
> reproduced here:
> Exercise 2.23.  The procedure for-each is similar to map. It takes as
> arguments a procedure and a list of elements. However, rather than
> forming a list of the results, for-each just applies the procedure to
> each of the elements in turn, from left to right. The values returned
> by applying the procedure to the elements are not used at all --
> for-each is used with procedures that perform an action, such as
> printing. For example,
> (for-each (lambda (x) (newline) (display x))
>          (list 57 321 88))
> 57
> 321
> 88
> The value returned by the call to for-each (not illustrated above) can
> be something arbitrary, such as true. Give an implementation of
> for-each.
> -----------------
> Using begin, this problem is quite simple, as below:
> (define (for-each fun items)
>  (cond [(not (null? items))
>         (begin
>           (fun (car items))
>           (for-each fun (cdr items)))]))
> (for-each (lambda (x) (newline) (display x))
>          (list 57 321 88))
> However, my problem is that SICP hasn't introduced begin yet, so i
> looked around online and saw someone else's solution as follows:
> (define (for-each2 fun items)
>  (cond [(not (null? items))
>         (fun (car items))
>         (for-each2 fun (cdr items))]))
> (for-each2 (lambda (x) (newline) (display x))
>          (list 57 321 88))
> It works as well, but can someone tell me why it works and if i did
> the following (which i thought is equivalent to the second one) and it
> wouldn't work:
> (define (for-each3 fun items)
>  (if (not (null? items))
>      (fun (car items))
>      (for-each3 fun (cdr items))))
> (for-each3 (lambda (x) (newline) (display x))
>          (list 57 321 88))
> Also why do we learn begin if one of the last 2 works.
> On a side note, the test code is provided in the book, and in the
> lambda expression, the author didn't use begin either....
> Thanks a lot for any clarifications provided :D
> Jason
> -- 
> "It's a wonderful world hobbes ol' buddy, let's go explorin'!" -
> Calvin in "Calvin and Hobbes"
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme 

Posted on the users mailing list.