[plt-scheme] Redefining in Mzscheme with legacy R5RS support
At Wed, 20 May 2009 14:29:45 +0300, Timo Lilja wrote:
> I want to run MzScheme with legacy R5RS support enabled but I came
> across with a bit strange behaviour:
>
> $ mzscheme -l scheme -l r5rs/run
> Welcome to MzScheme v4.1.5 [3m], Copyright (c) 2004-2009 PLT Scheme Inc.
> R5RS legacy support loaded
> > (define (filter pred x)
> (cond ((null? x) '())
> ((pred (car x)) (cons (car x) (filter pred (cdr x))))
> (else (filter pred (cdr x)))))
> > (filter (lambda (x) x) '(1 2 3))
> filter: expected argument of type <proper list>; given (2 3)
>
> === context ===
> [...]/lib/plt/collects/scheme/private/list.ss:182:2: filter stdin::1: filter
> [...]/lib/plt/collects/scheme/private/misc.ss:74:7
>
> However, if I redefine the filter once more in the REPL, then
> everything works:
>
> > (define (filter pred x)
> (cond ((null? x) '())
> ((pred (car x)) (cons (car x) (filter pred (cdr x))))
> (else (filter pred (cdr x)))))
> > (filter (lambda (x) x) '(1 2 3))
> (1 2 3)
>
> So it seems that if I invoke mzscheme with -l scheme -l r5rs/run,
> then, somehow, the recursive filter function is not entirely
> redefined. It looks like the recursive call to (filter pred (cdr x))
> still uses the original mzscheme language version which doesn't accept
> mutable pairs. Is this a bug or a feature?
You're seeing the same effect as described here:
http://www.cs.brown.edu/pipermail/plt-scheme/2006-December/015643.html
The `r5rs/run' library imports R5RS bindings into the top level in such
a way that they cannot be redefined (i.e., you get an error instead of
strange behavior if you try to redefine, say, `car'). But `-l scheme'
imports `scheme' bindings in the usual way, and the top level just
can't handle imports and redefinition gracefully.
If you really want to make this work, you can use functions like
`namespace-require/copy' that are designed to work around the hopeless
top level to some degree:
laptop% plt-r5rs --no-prim
Welcome to MzScheme v4.2.0.2 [3m], Copyright (c) 2004-2009 PLT Scheme Inc.
R5RS legacy support loaded
> (#%require (only scheme/base namespace-require/copy))
> (namespace-require/copy 'scheme)
> filter
#<procedure:filter>
> (define (filter x) (if x (filter #f) 'done))
> (filter #t)
done
This doesn't help with bindings to syntax, though, and it hurts
performance.