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

require/expose does not work on macros #152

Open
lihebi opened this issue Oct 16, 2021 · 4 comments
Open

require/expose does not work on macros #152

lihebi opened this issue Oct 16, 2021 · 4 comments

Comments

@lihebi
Copy link

lihebi commented Oct 16, 2021

require/expose can require an unprovided binding from a module. But it only works on functions, not macros. E.g.

(module aaa racket
  (define (foo a b) (+ a b))
  (define-syntax-rule (myadd x y)
    (+ x y)))
(require rackunit)
;; OK
(require/expose 'aaa (foo))
;; ERROR: myadd: use does not match pattern: (myadd x y)
(require/expose 'aaa (myadd))

The relative code blocks implementing require/expose:

(define (dynamic-require/expose* mod names)
;; Make sure module the module is instantiated
(dynamic-require mod #f)
;; Get the module namespace
(parameterize ((current-namespace (module->namespace mod)))
(apply values (map eval names))))

The reason is quite simple: transformer bindings are not available at runtime thus (apply eval names) thows error. Is it possible to make require/expose work on macros?

@jackfirth
Copy link
Collaborator

I don't think it's possible, nor do I think it's something we want to encourage in the first place. What were you planning to use this functionality for?

@lihebi
Copy link
Author

lihebi commented Oct 29, 2021

Thanks for your reply.

I'm developing a module-aware IDE for racket. In particular, a user develops code in one module (A) and requires it in another (B), and keeps doing this without restarting the racket runtime. Without require/expose, one has to re-declare module A every time a new function/macro is added to A, which is not very efficient when module A becomes large.

@jackfirth
Copy link
Collaborator

I don't think you need require/expose for that. You can use dynamic-rerequire instead, possibly combined with all-defined-out. You might also be interested in racket-reloadable, which uses dynamic-rerequire to implement hot code reloading for webserver-like programs.

@lihebi
Copy link
Author

lihebi commented Oct 30, 2021

Thanks for the pointers! If I understand correctly, you mean:

;; define module A with all-defined-out
(module A racket
  (provide (all-defined-out))
  (define a 1))
;; dynamically add a new binding b
(enter! 'A)
(define b 2)
(enter! #f)

;; try to reload
(dynamic-rerequire ''A)

;; OK
(dynamic-require ''A 'a)

;; ERROR: dynamic-require: name is not provided, name: 'b
(dynamic-require ''A 'b)

;; OK
(require/expose 'A (b))

Looks like this is not working, all-defined-out cannot pick up a new dynamically added binding. b.

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