A boiled down version of the language file "MyLang.rkt" follows:
#lang racket
(provide (rename-out [my-module-begin #%module-begin]))
(define-syntax (my-module-begin stx)
(syntax-case stx ()
[(_ real-lang body)
(syntax-case (local-expand #'(module m real-lang body) 'top-level (list)) ()
[(module nm lng (#%plain-module-begin . body2))
#'(#%plain-module-begin
;; use (only lng) to avoid conflicts with other require
(#%require (only lng))
. body2)])]))
It is used by "m.rkt":
(module m "MyLang.rkt" ;; MyLang acts as a meta-language
racket/base ;; which delegates to this language
(displayln "Hello")) ;; using this body
The problem I have is that "displayln" is highlighted with a blue-green background in DrRacket, indicating that it is provided by the module's language, but there is no arrow drawn from the "racket/base" just above.
If I change the last line of "MyLang.rkt" to put the fully-expanded module as a submodule (instead of merely extracting the contents of the #%plain-module-begin), then the arrow gets drawn:
#'(#%plain-module-begin (module nm lng (#%plain-module-begin . body)))
What conditions must be met for the arrow to be drawn?
#'(#%plain-module-begin (module nm lng (#%plain-module-begin . body2)))
Here is the modified "MyLang.rkt":
#lang racket
(provide (rename-out [my-module-begin #%module-begin]))
(define-syntax (my-module-begin stx)
(syntax-case stx ()
[(_ real-lang body)
(syntax-case (local-expand #'(module m real-lang body) 'top-level (list)) ()
[(module nm lng (#%plain-module-begin . body2))
#`(#%plain-module-begin
(#%require lng)
. #,((make-syntax-introducer) #'body2))])]))
And here's an example file using it:
(module m "MyLang.rkt"
;; delegates to this language:
typed/racket/base
;; body:
(begin
(require racket/set)
(displayln ;; arrow successfully drawn to typed/racket/base
(set ;; arrow successfully drawn to racket/set
"Hello"))))
Without the extra scope, I would get this error because racket/set shadows these bindings imported by typed/racket/base:
module: identifier already imported from a different source in:
for/set
racket/set
typed/racket/base
My problem seems solved, but if this extra-scope trick has some unwanted consequences, I would definitely want to hear about them!
On Dec 4, 2016, at 10:27 AM, Dupéron Georges <jahvascr...@gmail.com> wrote:I think I found a solution which allows me to inject the (#%require lng) without causing conflicts with other required module: applying an extra scope to the whole body makes the other (require) forms more specific, and they can shadow bindings imported by (#%require lng).
Here is the modified "MyLang.rkt":
#lang racket
(provide (rename-out [my-module-begin #%module-begin]))
(define-syntax (my-module-begin stx)
(syntax-case stx ()
[(_ real-lang body)
(syntax-case (local-expand #'(module m real-lang body) 'top-level (list)) ()
[(module nm lng (#%plain-module-begin . body2))
#`(#%plain-module-begin
(#%require lng)
. #,((make-syntax-introducer) #'body2))])]))