scheme

# Why doesn't this Scheme s-expression work when the sub expressions work?

``````> (equal? '(1 4) (car '('(1 4))))
#f
``````

Whoops, the above should evaluate to #t because the pieces result in #t

As follows:

``````> (car '('(1 4)))
'(1 4) ; Scheme doesn't get confused by list of a single list

> (equal? '(1 4) '(1 4))
#t. ; Scheme can see the equality of lists
``````

It must be some crazy scoping thing or address thing that equal? tests for things at the same address? If we break it down, we still get #f which suggests the equal? s-expression has its own scope?

``````> (define piece (car '('(1 4))))
> piece
'(1 4)
> (equal? '(1 4) piece)
#f

``````

equal? should be iterating over the members of each list being compared and return #t if all pairs of members are equal, which they are. So, this is weird and I must be fundamentally not understanding car or nested s-expressions.

It also fails in sbcl, so there is some dark mystical thing going on that I don't understand:

``````* (equalp '(1 4) (car '('(1 4))))
NIL
* (car '('(1 4)))
'(1 4)
* (equalp '(1 4) '(1 4))
T
*
``````

And it fails in Racket, too:

``````Welcome to DrRacket, version 8.9 [cs].
Language: racket/base, with debugging; memory limit: 128 MB.
> (equal? '(1 4) (car '('(1 4))))
#f
``````

Here is the definition of the member? function from Abelson and Sussman SICP:

``````(define (member? x list)
(if (null? list) #f
(if (equal? x (car list)) #t
(member? x (cdr list)))))
``````

I think I've written the exact same thing:

``````(define (my-member item lst)
(if (null? lst)
#f
(if (equal? item (car lst))
#t
(my-member item (cdr lst)))))
``````

So, I'm the problem but I don't understand. It seems semantically obvious.

Solution

• You have an extra quote. When you use quote, it quotes the entire expression, you don't need to quote the sub-expressions.

So it should be:

``````> (equal? '(1 4) (car '((1 4))))
#t
``````

When you quote the sub-expression, you're returning a list whose first element is the literal symbol `quote`. Since that's not equal to `1`, the two expressions aren't equal.