(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) >>
;; 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)))))
;;; 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)))
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.
>>>> -----
sritchie