Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow a macro to "reset" the elaborator and do all the elaboration passes within itself #87

Open
AlexKnauth opened this issue Jul 3, 2018 · 4 comments

Comments

@AlexKnauth
Copy link
Contributor

AlexKnauth commented Jul 3, 2018

Some macros, and specifically the mod macro in the Module/Functor system @iitalics and I are working on, should do all the elaboration passes themselves, and they should not be part of the elaboration passes of the outer module. Given this, they should call local-expand+elaborate to set up those passes. However, when submodules of an outer module expand, they are already within an elaboration pass, so the call to local-expand+elaborate errors out.

Should there be a call-with-no-elaborate-pass function or an extra argument to local-expand+elaborate so that macros like this can reset the elaborator and start a new set of passes?

Using the call-with-no-elaborate-pass function would look like this:

(call-with-no-elaborate-pass
  (λ ()
    (local-expand+elaborate ...expr...))))

Or using some kind of extra argument might look like this:

(local-expand+elaborate ...expr... #:reset? #true)

An implementation of call-with-no-elaborate-pass might look like:

(define (call-with-no-elaborate-pass f)
  (parameterize ([current-syntax-elaborate-pass #f]
                 [current-elaborate-did-make-progress? #f]
                 [current-elaborate-did-defer? #f]
                 [current-elaborate-defer-id #f])
    (f)))

Or an implementation of the #:reset? argument might look like:

(define (local-expand+elaborate stx #:reset? [reset? #f] [intdef-ctxs '()])
  ....
  (when (and (current-syntax-elaborate-pass) (not reset?))
    (raise-arguments-error 'local-expand+elaborate "already elaborating"))
  ....)
@lexi-lambda
Copy link
Owner

Should mod forms work like module*? That is, should they be expanded after the enclosing Racket module has been expanded and elaborated? Or should they be more like module submodules, which are expanded as soon as they are discovered?

@AlexKnauth
Copy link
Contributor Author

They currently work like module and not module*. Modules cannot refer to definitions from their enclosing modules, but definitions in an outer module can refer to submodules.

@AlexKnauth
Copy link
Contributor Author

AlexKnauth commented Jul 3, 2018

PS:
Even with a form that behaved more like module*, the mod form should ideally stay the same. It wouldn't be (def-module M (mod ....)) vs. (def-module M (mod* ....)), it would be:

(def-module M (mod ....))
vs.
(def-module* M (mod ....))

With the same mod form for both.

I'm imagining that the def-module form would expand right away while def-module* form would have its expansion delayed until after everything else in the enclosing module is expanded. And whether it's within one or the other, the mod form would want to do all the passes of the elaborator at that time.

@AlexKnauth
Copy link
Contributor Author

Would you rather have a function like call-with-no-elaborate-pass, or an optional extra argument like (local-expand+elaborate .... #:reset? #true)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants