The functionality you describe—in particular, setting up clean evaluation
contexts—sounds a lot like what the "Run" button already does. Unless you
have some other notion of "running" in mind for programs in your DSL, I
think what you describe could be accomplished nicely with a "main"
submodule, which (as you may know) is run only when its enclosing module is
invoked as a main program, not when it is required as a library. One
benefit is that this would make this functionality independent of DrRacket.

To illustrate what I mean, your source program:
#lang hypothetical-lanugage
(hypothetical-code)
would be transformed by the reader into:
(module example hypothetical-lanugage
  (#%module-begin
    (hypothetical-code)))
Then, your `#%module-begin` macro might expand to something like:
(module example hypothetical-lanugage
  (#%plain-module-begin
    (provide shape)
    (define shape (hypothetical-code))
    (module* main racket/base
      (require (submod "..")
               hypothetical-lanugage/private/render)
      (render shape))))

What I'm most unsure of about your question is that you say you want to use
a "C++ library that contains a function that takes in a module object as
input." Do you mean that you want to use the Racket C API
<https://docs.racket-lang.org/inside/Writing_Racket_Extensions.html#%28part._.Declaring_a_.Module_in_an_.Extension%29>
to create a new primitive module or something? That is not a very common
thing to do. Racket modules are not first-class values. While you can
produce a value representing the compiled form of a module (`
compiled-module-expression?
<https://docs.racket-lang.org/reference/Module_Names_and_Loading.html?q=module%20compi#%28def._%28%28quote._~23~25kernel%29._compiled-module-expression~3f%29%29>`)
by doing something like:
(compile '(module foo racket/base))
that is rarely what you want to do. In particular, the result of calling
`eval` is not a module (unless of course you do something like `(eval
'(compile '(module foo racket/base)) (make-base-namespace))`.

Calling `eval` on a module form, compiled or otherwise, merely declares the
module: it doesn't immediately do anything. For example, this expression:
(let ([ns (make-base-namespace)])
  (eval '(module effects racket/base
           (println "running"))
        ns)
  (println "module evaluated")
  (eval '(require 'effects) ns))
prints:
"module evaluated"
"running"
because the module isn't run until the `require` form is evaluated. Also,
`eval` handles expanding the program already: manual expansion is only
needed if you want to do some kind of static analysis.

-Philip

On Tue, Jun 25, 2019 at 6:02 PM Kshitij Sachan <kshitijsacha...@gmail.com>
wrote:

> I'm working on a DSL to represent 3D geometrical shapes. I'm adding a
> language-specific plugin (toolbar button) that should: 1) expand the source
> code to get a module object, 2) evaluate the module object, 3)
> dynamic-require that module object, 4) Create an OpenGL Context, 5)
> render this object using a C++ library that contains a function that takes
> in a module object as input and generates in the existing OpenGL context.
>
> Suppose my geometrical shape code is as follows:
> #lang hypothetical-lanugage
>
> (hypothetical-code)
>
> I have a couple questions on how to set this up:
>
>    1. The documentation on drracket:eval:expand-program
>    
> <https://docs.racket-lang.org/tools/drracket_eval.html#%28def._%28%28lib._drracket%2Ftool-lib..rkt%29._drracket~3aeval~3aexpand-program%29%29>
>     is rather dense, and I don't understand what the parameters should
>    be. Could you please provide me with a minimum working example of how to
>    call this function?
>    2. Is the output of drracket:eval:expand-program
>    
> <https://docs.racket-lang.org/tools/drracket_eval.html#%28def._%28%28lib._drracket%2Ftool-lib..rkt%29._drracket~3aeval~3aexpand-program%29%29>
>  directly
>    suitable to be called as the argument to the eval function? If not,
>    what kind of preprocessing do I need to do before calling eval?
>    3. Will the result of eval be a module object?
>    4. If I press the toolbar button twice, will dynamic-require work or
>    do I need dynamic-rerequire? Essentially what I'm asking is do I get a
>    clean evaluation context each time I press my toolbar button?
>    5. Is it good style for my button to save the source code each time I
>    run it? If so, how can I do that?
>    6. Ideally, I'd like the OpenGL rendering to appear as a third window
>    to accompany the interactions and definitions window. Is there any way to
>    do that?
>
> Thanks!
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/179b48af-cfe1-4d6a-8c11-6f27584a4129%40googlegroups.com
> <https://groups.google.com/d/msgid/racket-users/179b48af-cfe1-4d6a-8c11-6f27584a4129%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAH3z3gaE95ihz-p90VcuyV0DO9DkKRr4Gr8PDshyq81vUQRjXg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to