[racket-dev] using module system for alternate namespaces

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Mon Oct 27 21:46:30 EDT 2014

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

Posted on the dev mailing list.