[racket-dev] using module system for alternate namespaces
I'm having trouble understanding the problem.
In your example, is 'base the namespace API that you have available?
It has a way of referencing an identifier and making a binding? And
you are looking at a way to take modules like 'm1 (which are really
written using this namespace mechanism) and then turn them into Racket
modules? So, there is some pre-existing thing like 'm1 and you want to
turn it into a Racket-y thing that doesn't need to explicitly use the
namespace API?
If that is mostly accurate, then here are some ideas:
- If the other namespaces are fixed before the program runs, then you
can make them constructed through a macro that uses the namespace API
to query the namespace and set up bindings in (sub)modules that call
the reference function, some thing:
(define-syntax-rule (define-module-of namespace-id)
(module namespace-id namespace/reflect namespace-id))
where namespace/reflect is a module language that has a #%module-begin like
(define-syntax (#%module-begin stx)
(syntax-case stx ()
[(_ . namespace-id)
(with-syntax ([(id ...) (namespace-binding-list (syntax->datum
#'namespace-id))])
(syntax (begin (define id (namespace-get 'namespace-id 'id)) ...
(provide (all-defined-out)))))]))
Then your Racket code could just (require (submod "." 'whatever)) and
get the macro-generated 'whatever namespace as Racket bindings.
This would work with separate compilation.
- If the other namespaces are dynamically created with the Racket
program, then you could follow a similar technique, but create an
evaluator in the main Racket program and then generate a call to
(define-module-of n) when the n namespace was ready and then inject a
Racket expression that wants to use those bindings into the evaluator
or something like that.
- I feel like this is vaguely similar to how the Web server's
templating system works.
Jay
On Mon, Oct 27, 2014 at 7:00 PM, Dan Liebgold <dan.liebgold at gmail.com> wrote:
> I have a namespace behind a particular API. I'd love to hook into the module
> system to control compilation, visibility, etc. of all the definitions and
> references.
>
> Here's an example. 'a' is available in the top level module even though it
> was defined by module 'm1' and not provided by any explicit mechanism.
> (Also, order dependencies seem imminent.)
>
> #lang racket
>
> (module base racket
> (define my-table (make-hasheq))
>
> (define-syntax (my-define stx)
> (syntax-case stx ()
> [(_ my-id expr) (identifier? #'my-id)
> #'(hash-set! my-table 'my-id expr)]))
>
> (define-syntax (my-eval stx)
> (syntax-case stx ()
> [(_ my-id)
> #'(hash-ref my-table my-id #f)]))
>
> (provide my-define
> my-eval)
> )
>
> (module m1 racket
> (require (submod ".." base))
> (my-define a (+ 1 2))
> )
>
> (require 'base
> 'm1)
>
> (my-eval 'a)
>
>
> Is there any example of doing something like this using the module system
> without polluting the top level namespace? Am I correct in assuming that
> this will not work under separate module compilation?
>
> --
> Dan Liebgold [dan.liebgold at gmail.com]
>
> _________________________
> Racket Developers list:
> http://lists.racket-lang.org/dev
>
--
Jay McCarthy
http://jeapostrophe.github.io
"Wherefore, be not weary in well-doing,
for ye are laying the foundation of a great work.
And out of small things proceedeth that which is great."
- D&C 64:33