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

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Mar 8 09:46:14 EST 2011

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)
  > (define (foo x y) 0)
  > (bar 2 2) ; the "recursive" call calls the above `foo'
  > (bar 2 0) ; don't call it, so this uses the original code only

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!

Posted on the users mailing list.