filter: contract violation expected: list?
morbidCode opened this issue · 3 comments
There is something odd about filter when the sicp package is required. Here's my code.
(require sicp)
(print-as-expression #f) ; for printing lists
(#%require r5rs/init) ; for printing lists
(filter (lambda (x) #t) (list ))
()
(filter (lambda (x) #t) (list 1))
; filter: contract violation
; expected: list?
; given: (1)
; [,bt for context]
I don't know what caused filter to act so strangely...
The problem is that lists in Racket and Scheme (SICP/R5RS) are different.
Racket lists are immutable and Scheme lists are mutable.
In #lang sicp and #lang r5rs lists are built using mcons (short for mutable cons) and the empty list. In Racket lists are built using cons and the empty list.
Therefore filter from racket/list doesn't work with list created by Scheme.
Since filter is not part of R5RS the easiest is to define your own version:
#lang sicp
(define (filter pred xs)
(if (null? xs)
'()
(if (pred (car xs))
(cons (car xs) (filter pred (cdr xs)))
(filter pred (cdr xs)))))
I forgot to write that (require sicp) imports the list used by SICP/R5RS so the (list 1) in your example produces a list built with mcons.
Got it. Thanks.