Search code examples
schemechez-schemethe-little-schemer

Why is (atom? (car '('bacon 'and 'eggs))) different from (atom? 'bacon) in ChezScheme?


I'm going through The Little Schemer in ChezScheme and in chapter 2 I run through the following problem. I write the definition of lat? according to the book.

(define lat?
    (lambda (l) 
        (cond 
            ((null? l) #t) 
            ((atom? (car l)) (lat? (cdr l)))
            (else #f)
        )
    )
)

Then a define a list

(define l '('bacon 'and 'eggs))

and then

(lat? l)

evaluates to #f.

It seems that the issue is that while (car l) evaluates to 'bacon and atom? 'bacon evaluates to #t, (atom? (car l)) evaluates to #f.


Solution

  • You need to change the definition to

    (define l '(bacon and eggs))
    

    Explanation

    The expression

    '('bacon 'and 'eggs)
    

    is shorthand for

    (quote ((quote bacon) (quote and) (quote eggs)))
    

    Inside a quote, every expression is taken literally and has no special meaning, so the quote in (quote bacon) is just another symbol. The car of '('bacon 'and 'eggs) is (quote bacon), which is itself a list, not an atom.

    REPL differences

    One potential point of confusion is that different Scheme REPLs print expressions differently. For example, Racket prints expressions with an explicit quote, whereas Chez Scheme does not.

    Racket v8.7:

    > (car '(a b c))
    'a
    

    Chez Scheme v10.0.0:

    > (car '(a b c))
    a
    

    Each expression evaluates to the same value. The difference is purely stylistic.

    So when Chez Scheme's REPL shows 'bacon, it means that the value is the list (quote bacon).