Difference between if and cond?

I am studying sicp now and doing ex2.23 I wrote the following code:

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

but at startup they cause an error: procedure: expected procedure, given: #; arguments were :()

I think I know the reason: I call each function recursively, each called - everyone wanted to return a value

but when i changed the code:

 (define (for-each proc items) (cond ((null? items) #t) (else (proc (car items)) (for-each proc (cdr items))))) 

It works well. I do not understand why? in cond , each called for each - no need to return a value?

I used DrScheme and chose the SICP language

I am not a native speaker of English, so if there is sth that is not described clearly, pls tell me

+4
source share
1 answer

but at startup it raises an error: application: expected> procedure, given: #; arguments were :()

I think I know the reason: I call recursively for each function,> each called for - everyone wanted to return a value

No, this is because in the alternative if section you have the combination ((proc (car items)) (for-each proc (cdr items))) . You intended to consistently evaluate two combinations (proc (car items)) and (for-each proc (cdr items)) , and for this purpose you thought about putting them in another pair of parentheses. But in reality, what you have indicated is that the result (proc (car items)) is the procedure applied to the argument, which is the return value (for-each proc (cdr items)) . This is not the case and you get an error message. The key point is that parentheses in Lisp are not intended to be grouped, but they do have a certain meaning.

The problem is that if can only have one combination at this position, whereas you want to have two lines. Cond, on the other hand, does not suffer from such a restriction; you can put as much of the sequence of individual combinations as possible into the next part of the cond sentence, as your heart desires. This state of affairs is simply how a language is defined to work.

In these situations, you can use cond , but if you still want to use if , there are several options for adding multiple combinations to one. E. g. you can create a lambda procedure, the body of which consists of two combinations and immediately turn it off:

  (define (for-each proc items)
    (if (null? items)
        #t
        ((lambda ()
           (proc (car items))
           (for-each proc (cdr items))))))

Or you can use begin , which is actually intended to be used for such a purpose:

  (define (for-each proc items)
    (if (null? items)
        #t
        (begin
           (proc (car items))
           (for-each proc (cdr items)))))
+7
source

All Articles