AND procedure in terms of IF for arbitrary number of argument
(define (and . xs) (if (null? xs) #t (if (null? (cdr xs)) (car xs) (if (car xs) (apply and (cdr xs)) #f))))
OR procedure for arbitrary number of arguments
(define (or . xs) (if (null? xs) #f (if (null? (cdr xs)) (car xs) (if (car xs) (car xs) (apply or (cdr xs))))))
These are such a mess due to the fact that we must "extract parameters from a list" (do destructuring) and analyze two special cases (dealing with varying number of arguments) in the same piece of code. In other dialects these constructs do look slightly better.
We also could re-write it to look slightly better
(define (last? xs) (and (pair? xs) (null? (cdr xs)))) (define (and . xs) (cond ((null? xs) #t) ((last? xs) (car xs)) (else (if (car xs) (apply and (cdr xs)) #f))))
but it is cheating, because we presumably still do not have
Now let's turn these into special forms. The idea is that we do not want to evaluate rest of the argument expressions if we have already reached the base case - a
false value for AND or a
true value for OR.
How do we create new special forms? By writing them as a macro.