[racket] Different behavior when using (#%require scheme/base)

From: Jos Koot (jos.koot at telefonica.net)
Date: Tue Mar 8 14:56:55 EST 2011

The module system works very nicely, especially since it is allowed to
redefine foo in a module that already implicitly imports foo. The module
system does respect the scope of modules. The only thing you cant and you
should not want to do is to import the same identifier from two different
modules (with distinct definitions) into one and the same module. I rarily
use the repl (interactions window) of DrRacket. Use #lang in the definitions
window. The repl top level really is a disastre. Is there any chanche to
abandon the repl completely? Quit the interactions window, except as a
current-output-port? Quiting the repl should also allow a program to do much
more garbage collection after completion (and even before completion,
because transformers could already be discarded immediately after expansion)

> -----Original Message-----
> From: users-bounces at racket-lang.org 
> [mailto:users-bounces at racket-lang.org] On Behalf Of Eli Barzilay
> Sent: 08 March 2011 15:46
> To: Yaron Gonen
> Cc: users at racket-lang.org; Sam Tobin-Hochstadt
> Subject: Re: [racket] Different behavior when using 
> (#%require scheme/base)
> 20 minutes ago, Yaron Gonen wrote:
> > Thanks for the fast reply.
> > One thing I don't understand: 'exp' is bounded without
> > scheme/base. What is so special about the new binding in
> > scheme/base?  For example, the following code works fine:
> > 
> > (define foo
> >   (lambda (x)
> >     (* x x)))
> > 
> > (define foo
> >   (lambda (b e)
> >     (if (= e 0) 1
> >         (* b (foo b (- e 1))))))
> If you start with this definition, the compiler doens't know what
> `foo' is when it compiles the body, so it inserts code that always
> looks up whatever `foo' is bound to on every call, which means that
> the function will do a recursion as long as `foo' is bound to it.
> This might seems like an odd "as long as", but here's how you can see
> it having an effect:
>   > (define bar foo)
>   > (bar 2 2)
>   4
>   > (define (foo x y) 0)
>   > (bar 2 2) ; the "recursive" call calls the above `foo'
>   0
>   > (bar 2 0) ; don't call it, so this uses the original code only
>   1
> Now, if you do both definitions, you still get the same situation: the
> compiler still doesn't know about `foo' because definitions that are
> done dynamically (as the r5rs language does) basically mark the
> defined name (`foo' in this case) as something that should always be
> looked up dynamically.
> Going back to Matthew's "The top level is hopeless" -- in the Racket
> context, his argument is roughly translated into "Use the module
> system, and you'll have no such probolems".  The thing is that the
> dynamic top-level work is something that *usually* works, but
> sometimes bites in a very confusing way (and you were unfortunate to
> run into such a case).
> -- 
>           ((lambda (x) (x x)) (lambda (x) (x x)))          
> Eli Barzilay:
>                     http://barzilay.org/                   
> Maze is Life!
> _________________________________________________
>   For list-related administrative tasks:
>   http://lists.racket-lang.org/listinfo/users

Posted on the users mailing list.