sicp-ex-2.23


 (define (for-each proc items) 
   (let ((items-cdr (cdr items))) 
     (proc (car items)) 
     (if (not (null? items-cdr)) 
         (for-each proc items-cdr) 
         true))) 

<< Previous exercise (2.22) | Index | Next exercise (2.24) >>


sritchie

  
  
  
 ;; I didn't find that any of the other implementations here 
 ;; supported the null list as input; here's my fix. 
 ;; for-each 
  
 (define (for-each proc list) 
   (cond 
    ((null? list) #t) 
    (else (proc (car list)) 
          (for-each proc (cdr list))))) 
  


jz

  
 ;; for-each 
  
  
 ;; The below didn't work ... basically, I needed some kind of block 
 ;; structure, since if has the form (if (test) true-branch 
 ;; false-branch).  I needed to have true-branch execute the proc, then 
 ;; call the next iteration of for-each, and the only way I knew how to 
 ;; do that was with brackets ... but of course that doesn't work, as 
 ;; the interpreter tries to apply the result of the first proc call as 
 ;; a function to the rest. 
 (define (for-each proc items) 
   (if (not (null? items)) 
       ((proc (car items)) 
       (for-each proc (cdr items))))) 
  
 (for-each (lambda (x) (newline) (display x)) (list 1 2 3 4)) 
  
  
 ;; This one works. 
 ;; Moral: cond is better for multi-line branches. 
 (define (for-each proc items) 
   (cond ((not (null? items)) 
          (proc (car items)) 
          (for-each proc (cdr items))))) 
  
  


tyg

  
  
  
 ;;; First, I'm sorry for using common lisp. 
 ;;; This is an easy but funny problem, At a first glance, I think I need some 
 ;;; block structure such as cond, progn, etc., in fact, you can use function 
 ;;; argument eval rule to avoid using them at all. I think this solution has  
 ;;; more 'functional style'. 
  
  
 (defun for-each (f items) 
   (labels ((iter (action lst) 
              (if (null lst) 
                  action 
                  (iter (funcall f (car lst)) (cdr lst))))) 
     (iter nil items))) 

amasad

  
 ; :) 
  
 (define (for-each proc items) 
   (map proc items) 
   #t) 
  

AMS

The above solution by amasad is incorrect as MAP is different to FOR-EACH. Map will create a LIST of the results whereas we don't want the output of For-each to create a list, just to apply the specified procedure to each of the list elements.

The solution by amasad is perfectly fine. It returns true, it doesn't matter if internally it "creates a list" or whatever. In fact, I'd say this'd be fine too:

 (define for-each map) 

as the exercise states that the result can be arbitrary, so it can arbitrarily be the list of items in the list applied to the given procedure.



wbooze

  
  
  
 ;;; i did the same with common-lisp 
 ;;; it pretty much matches the first scheme form on this page tho! 
  
 (defun for-each (proc items) 
   (if (null items) 
       nil 
       (apply proc (car items) nil)) 
   (if (not (null (cdr items))) 
       (for-each proc (cdr items)))) 
  

anonymous

  
  
  
 ;; Another way to use if instead of cond. 
 ;; We just wrap the multiple statements in a let. 
 ;; From: http://wiki.drewhess.com/wiki/SICP_exercise_2.23 
  
 (define (for-each proc items) 
   (if (not (null? items)) 
       (let () 
         (proc (car items)) 
         (for-each proc (cdr items))))) 

coriolis

  
  
 (define (for-each unary-proc seq) 
        (if (null? seq) 
            (newline) 
            (unary-proc (car seq)) (for-each unary-proc (cdr seq)) ) )