S Kim
S Kim

Reputation: 13

Having trouble converting if into cond

I'm trying to understand why these two functions are giving me different results. Is there some case that I am missing when I converted the nested if statements into conds? The functions are supposed to count elements in a list recursively.

(define (countall x L)
    (if (null? L) 0
        (if (pair? L) (+ (countall x (car L)) (countall x (cdr L)))
            (if (eq? x L) 1 0)
        )
    )
)
(countall 'a '(a (a))) ;gives 2

(define (countall x L)
    (cond
        ((null? L) 0)
        ((pair? L) (+ (countall x (car L)) (countall x (cdr L))))
        (else (eq? x L) 1 0)
    )
)
(countall 'a '(a (a))) ;gives 0?

I've tried stepping through by hand, but I'm having a hard time finding what's going wrong.

Upvotes: 1

Views: 52

Answers (1)

sepp2k
sepp2k

Reputation: 370162

Your else case contains three different expressions: (eq? x L), 1 and 0. This is treated like a begin block (one might say that each case of a cond automatically starts a begin block), meaning that all three expressions are evaluated in order and then the value of the last expression is returned. So your else case always returns 0 regardless of whether x equals L or not.

(eq? x L) shouldn't be an expression in the else block, it should be one of the conditions of your cond. So it should be:

(cond
    ((null? L) 0)
    ((pair? L) (+ (countall x (car L)) (countall x (cdr L))))
    ((eq? x L) 1)
    (else 0))

Upvotes: 2

Related Questions