[plt-scheme] local-expansion interaction with class.ss
I'm new to using mzscheme macros, and so I apologize if the answer to
these questions is as simple as pointer to the correct paragraph of
documentation.
I'm trying to build an extension language on top of the standard
mzscheme that redefines #%app to preprocess the call through a simple
wrapper function:
(module my-lang mzscheme
(define-syntax my-app
(syntax-rules ()
((_ f a ...)
(app/wrapper f a ...))))
(define (app/wrapper fun . args)
;; various processing
(apply fun args))
(provide (all-from-except mzscheme #%app))
(provide (rename my-app #%app))
)
This works well for many programs; however, if those programs use the
standard class.ss library, this causes issues:
(module objects-test my-lang
(require (lib "class.ss"))
(define cls%
(class object%
(define/public (some-method a)
(printf "Method invoked: ~a\n" a))
(super-new)
(some-method "Implicit Send")))
)
Here, some-method is converted to a macro that only works in the
application position; so when the my-app macro rewrites (some-method
"Implicit Send") to (app/wrapper some-method "Implicit Send"), it
complains with:
class: misuse of method (not in application) in: some-method
It seems that I can get past this difficulty by using local-expand to
remove all macros from the syntax before transforming it. An initial
attempt at putting local-expand inside the my-app macro was a
failure, causing infinite recursion as it repeatedly tried to expand
itself.
Instead, it seems that I'll have to do the the expansion earlier. I
chose to replace #%module-begin, and do the expansion in there; but
even before adding my-app back in, I encountered a problem. Here's an
example:
(module a mzscheme
(provide (all-from-except mzscheme #%module-begin))
(provide (rename my-module-begin #%module-begin))
(define-syntax (my-module-begin stx)
(syntax-case stx ()
[(_ e ...)
(begin
(printf "Transforming Module:\n")
(printf "~s\n" (syntax-object->datum stx))
(let* ([expanded (local-expand (syntax (#%module-begin e ...))
(syntax-local-context)
null)])
(printf "expanded:\n")
(printf "~s\n" (syntax-object->datum expanded))
expanded))]))
)
(module b a
(require (lib "class.ss"))
(define cls% (class object%
(super-new)))
)
(require b)
Here, the transformation takes place as expected, but the compilation
fails with the error:
/Users/jdm352/Library/PLT Scheme/360/collects/mzlib/private/class-
internal.ss:1296:85: compile: identifier used out of context in:
super-go
Why is this the case? My understanding (weak as it is) was that
expansion would preserve all the contexts required (how else could
the compiler work, for example?). Clearly, I've got a fundamental
misunderstanding about the macro system, and reading the docs and
papers is leaving me scratching my head in further confusion.
Is this local-expansion plan the correct way to solve the problem? If
so, why does it lose the proper context for super-go and other
identifiers?
Much thanks for any help you can point me to.
Jim