[racket-dev] Confusion of difference of evaluating syntax vs compiled code?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Apr 7 08:47:37 EDT 2013

At Thu, 4 Apr 2013 15:34:18 -0600, Danny Yoo wrote:
> I'm running into dynamic evaluation behavior that I don't quite
> understand yet.  My example is:
>     https://gist.github.com/dyoo/5314045
> It's meant as an experiment to see whether it's possible to avoid 3d
> syntax in certain places like the gui-debugger.  I try to throw in a
> wrench on lines 52-54:
>     https://gist.github.com/dyoo/5314045#file-annotation-example-rkt-L52-L54
> but thankfully, when I evaluate this in DrRacket, I get the results I expect.
> However, that's when I'm evaluated the annotated+compiled code.  If I
> modify the example so I'm evaluating just the annotated code, by
> modifying lines 117-119
> https://gist.github.com/dyoo/5314045#file-annotation-example-rkt-L117-L119
> from:
>     ;; But we can evaluate it in ns:
>     (printf "evaluating the annotated code\n")
>     (eval compiled-code ns)
> to:
>     ;; But we can evaluate it in ns:
>     (printf "evaluating the annotated code\n")
>     (eval annotated-code ns)
> I get the unexpected shadowing I'm trying to avoid.  Why am I getting
> the clash here, and not in the compiled code?

When you use

  (eval annotated-code ns)

it's the same in this example as

 (map (lambda (c) 
        (define compiled-c
          (parameterize ([current-namespace ns])
            (compile c)))
        (eval compiled-c ns))
      (cdr ; drop `begin'
       (syntax->list annotated-code)))

That is, `eval' splices a top-level `begin' and evaluates earlier
spliced forms before it compiles later spliced forms. 

The `eval' function must interleave evaluation and compilation to make
various things work --- even though interleaving breaks various other
things, including your example. The top level is hopeless.

Posted on the dev mailing list.