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

> (equal? '(1 4) (car '('(1 4))))

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)

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))))
* (car '('(1 4)))
'(1 4)
* (equalp '(1 4) '(1 4))

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))))

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)
    (if (equal? item (car lst))
      (my-member item (cdr lst)))))

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


  • 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))))

    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.