[racket] `namespace-set-variable-value!` doesn't "shadow"? How to do?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sun Nov 24 18:54:52 EST 2013

At Sun, 24 Nov 2013 14:46:03 -0500, Greg Hendershott wrote:
> The code below is from
> https://github.com/greghendershott/frog/blob/f9bda203b4b26d8f24bc466db93979a015
> 873512/frog/template.rkt
> 
> [...]
> 
> (define/contract (render-template dir filename dict)
>   (path? path-string? dict? . -> . string?)
>   (define template-namespace (make-empty-namespace))
>   (define (attach/require m) ; symbol? -> void
>     (namespace-attach-module (current-namespace) m template-namespace)
>     (parameterize [(current-namespace template-namespace)]
>       (namespace-require m)))
>   (attach/require 'web-server/templates)
>   (attach/require 'frog/widgets)
>   (for ([(k v) (in-dict dict)])
>     (namespace-set-variable-value! k v #f template-namespace))
>   (define to-eval
>     #`(include-template #,(datum->syntax #'render-template filename)))
>   (parameterize ([current-directory dir])
>     (eval to-eval template-namespace)))

I'm not clear on what you're trying to do, but I wonder about the
`datum->syntax` conversion to produce `to-eval`. That causes the
expression to evaluate to have the lexical context of the module
containing `render-template`, instead of the top-level lexical context
of the namespace where you're evaluating the template.

In other words, I think you want

   (define to-eval
     `(include-template ,filename))

Then, passing #t as the third argument to
`namespace-set-variable-value!` will shadow any bindings imported from
`web-server/templates` and `frog/widgets` into the namespace.


Posted on the users mailing list.