2

I am working on the SICP book. I am using SCM on Windows instead of the actual Scheme program. When I run the Filter function below I get (1 3 5 . #f) as shown below in the code window. I cannot understand how the dot and false value are being appended to the odd integers.

    (define (filter odd? lst)
        (cond ((null? lst) nil)
              ((odd? (car lst))
               (cons (car lst)
                     (filter odd? (cdr lst))))
              (else (filter odd? (cdr lst)))))

    (filter odd? (list 1 2 3 4 5))

    (1 3 5 . #f)

I am expecting to get (1 3 5) as the result rather than (1 3 5 . #f).

Kris
  • 45
  • 3

3 Answers3

2

nil isn't a Scheme report defined top level binding today. If it exists in an implementation it can be any value so you cannot depend on it. SICP used a earlier version of Scheme than R4RS and thus no modern implementations today will support it fully. I use DrRacket since it supports many of the report languages, has a nice debugger and IDE, and the chances of syntax errors is lessened by the fact it indents the code while writing. It has a SICP compatibilty language so that SICP code works without having to jump through too many hoops.

Historically Scheme came from Lisp and Lisp doesn't differentiate between the empty list and false value. Scheme introduced #t and #f but kept the fact that the empty list was considered false until they changed it so that only #f is false and everything else is considered truthy. nil was a binding for () in early reports so it might be that SCM changed it to #f when they did the change since CL often use nil for the false value and () for the empty list, even though they are just two representations of the same value.

Lots of implementations introduce their own bindings on top of the report they are compliant with. Using them locks you in to their flavor so the best is to keep the code standard. DrRacket interprets the reports in a very strict manner than other implementations such that a R6RS program written in DrRacket most likely will run without changes in other R6RS compliant implementations. Standards are cool that way!

Sylwester
  • 47,942
  • 4
  • 47
  • 79
0

When I get behavior I don't understand I add debugging output to the program. What happens when you say:

(define (filter odd? lst)
    (display lst) (newline)
    (cond ((null? lst) (display "1") (newline) nil)
          ((odd? (car lst))
            (display "2") (newline)
            (cons (car lst)
                  (filter odd? (cdr lst))))
          (else (display "3") (newline)
                (filter odd? (cdr lst)))))

You will see the arguments passed on every recursive call, and you will know what branch of the cond was selected at each recursive call. That usually shows me the problem.

user448810
  • 17,381
  • 4
  • 34
  • 59
  • DrRacket has a debugger. you can set breakpoints and even step through the code. IMHO much better than adding print statements. – Sylwester Apr 19 '19 at 16:53
0

I think the issue is with the line:

    (cond ((null? lst) nil)

and the value of nil. In the book's falvour of scheme I belive nil is equivalent to the empty list '(). I suspect SCM considers nil to be equivalent to false, #f. So if you replace nil with '() you may get the expected results.

codybartfast
  • 7,323
  • 3
  • 21
  • 25