[plt-scheme] Wrapping non-PLT code in modules
At Tue, 29 Oct 2002 12:21:30 -0500, "Anton van Straaten" wrote:
> So, I tried providing a relative path to collects/lang/r5rs.ss. This failed
> because of not having "provide" and "require" defined in that "language".
> So I copied r5rs.ss and added "provide" and "require" to its provide
> statement. That worked! Cool. (I think. I haven't run into any
> show-stopping problems with it yet...)
>
> My question is, is there a simple|recommended|obvious way to do this that
> I've missed?
I expected the recommended way to be simple and obvious, but it isn't.
Requiring and re-exporting `(lib "r5rs.ss" "lang")' is tricky --- too
much overlap with `mzscheme', and not enough renaming operators within
`provide'.
The simplest way I can recommend replies on one helper module:
; ----------------------------------------
(module almost-nothing mzscheme
(provide #%module-begin
provide
require))
(module r5rs-rpi "almost-nothing.ss"
(require (all-except (lib "r5rs.ss" "lang") #%module-begin)
(rename (lib "r5rs.ss" "lang") r5rs-module-begin #%module-begin)
(lib "include.ss"))
(provide (all-from (lib "r5rs.ss" "lang"))
(rename r5rs-module-begin #%module-begin)
require
provide
include))
(module wrapped-demo "r5rs-rpi.ss"
(include "demo.scm")
(provide foo goo)) ; if foo & goo are defined in demo.scm
; ----------------------------------------
Then I decided to go for something a little fancier. Suppose I don't
want `require', `provide', and `include' bound in my R5RS code. Here's
one way.
; ----------------------------------------
(module r5rs-wp "almost-nothing.ss"
(require (all-except (lib "r5rs.ss" "lang") #%module-begin)
(rename (lib "r5rs.ss" "lang") r5rs-module-begin #%module-begin)
(lib "include.ss"))
;; defines a module top-level that contains just a file
;; name and a parenthesized sequence of exports
(define-syntax (wrap-module-begin stx)
(syntax-case stx ()
[(_ file-name (export ...))
(string? (syntax-e #'file-name))
#'(r5rs-module-begin
(include-at/relative-to file-name file-name file-name)
(provide export ...))]))
(provide (all-from (lib "r5rs.ss" "lang"))
#%module-begin
provide
wrap-module-begin))
(module r5rs-wrap "r5rs-wp.ss"
(provide (all-from-except "r5rs-wp.ss" provide #%module-begin)
(rename wrap-module-begin #%module-begin)))
(module wrapped-demo "r5rs-wrap.ss"
"demo.scm"
(foo goo))
; ----------------------------------------
Amusing, but even in this case, `#%module-begin' is still bound in the
R5RS code. For that matter, so is `#%app', etc. But those are not legal
R5RS identifiers.
Ok, so why not just add `#%require' and `#%provide' to the exports of
`(lib "r5rs.ss" "lang")'? Done.
; ----------------------------------------
(module wrapped-demo (lib "r5rs.ss" "lang") ; <- the new r5rs.ss
(#%require (rename (lib "include.ss") #%include include))
(#%include "demo.scm")
(#%provide foo goo))
; ----------------------------------------
Matthew