[plt-scheme] Injecting syntax into load
Danny, hello.
On 2006 Dec 7 , at 18.16, Danny Yoo wrote:
> On Thu, 7 Dec 2006, Norman Gray wrote:
>
>> Can anyone tell me how I would inject new syntax into the syntax
>> transformer used by LOAD, in such a way that REQUIRE in the loaded
>> file works?
>
> Here's an example that might help:
Hero! Thanks for this -- it's extremely helpful.
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (module test mzscheme
> [...]
> Namespaces affect EVAL, so whenever we want to do something with
> them, we either need to use the namespace-specific functions, or
> EVAL/LOAD.
The following variant of your snippet made the discinction a little
clearer to me:
;;;;;;;;;;;;;;;;
(define n-expr 0)
(define (inc-n)
(set! n-expr (+ n-expr 1)))
(parameterize ([current-namespace (make-namespace)])
(namespace-transformer-require 'mzscheme)
(eval `(define another ,inc-n)) ; change
(eval
'(begin
(define-syntax (double stx)
(syntax-case stx ()
[(_ x)
(syntax/loc stx
(begin (another) ; change
(list x x)))]))))
(let loop ([s-expr (read)])
(cond [(eof-object? s-expr) 'done]
[else
(display (format "~a: ~a~%" n-expr (eval s-expr)))
(loop (read))])))
(display (format "~a doubles evaluated~%" n-expr))
;;;;;;;;;;;;;;;;;;;;
Thus even within the parameterised namespace, the non-EVALed
expressions are still acquiring the bindings of the `parent'
environment; it's only EVAL (and, as you say, LOAD) that evaluates
things in the new namespace. I wasn't getting this (as well as not
twigging the significance of namespace-transformer-require).
That's intelligible in retrospect: this is exactly what the
documentation for EVAL says (in Section 14.1); what I'm only now
understanding is that this is a contentful remark, since it is
distinct from the reading-and-evaluating being done as this
expression as a whole is read.
I see a clue coming (thud!): when the PARAMETERIZE expression is
read, that reading is done, syntax is expanded, and the identifiers
bound, in the environment in which INC-N is defined. When the EVALs
are evaluated, however, that's done in the fresh environment/
namespace in which INC-N is not defined. Omitting the PARAMETERIZE,
and having the call to CURRENT-NAMESPACE at the top level, breaks the
above example, for reasons which I now (think I) understand.
Scheme _is_ simple, isn't it...
Thanks again for the insight. Best wishes,
Norman
--
------------------------------------------------------------------------
----
Norman Gray / http://nxg.me.uk
eurovotech.org / University of Leicester, UK