[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!