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

syntax/module-reader is brittle #2368

Open
sorawee opened this issue Nov 13, 2018 · 4 comments
Open

syntax/module-reader is brittle #2368

sorawee opened this issue Nov 13, 2018 · 4 comments

Comments

@sorawee
Copy link
Collaborator

sorawee commented Nov 13, 2018

Depending on where the running file is, Racket might or might not find a module.

For example, consider the example from https://docs.racket-lang.org/guide/syntax_module-reader.html:

;; /path/to/raquet.rkt
#lang s-exp syntax/module-reader
"raquet-mlang.rkt"

;; /path/to/raquet-mlang.rkt
#lang racket
(provide (except-out (all-from-out racket) lambda)
         (rename-out [lambda function]))

;; /path/to/a.rkt
#lang reader "raquet.rkt"
(define identity (function (x) x))
(print (identity 5))

This runs without any problem.

Now, create a new file:

;; /path/to/test/b.rkt
#lang reader "../raquet.rkt"
(define identity (function (x) x))
(print (identity 5))

Running it, we get this error:

/path/to/test $ racket b.rkt
open-input-file: cannot open module file
  module path: /path/to/test/raquet-mlang.rkt
  path: /path/to/test/raquet-mlang.rkt
  system error: no such file or directory; rktio_err=3
@mbutterick
Copy link
Collaborator

mbutterick commented Nov 17, 2018

Right, because when you invoke a #lang like so:

;; /path/to/test/b.rkt
#lang reader "../raquet.rkt"
(define identity (function (x) x))
(print (identity 5))

You end up with the equivalent module expression, which looks like this:

;; /path/to/test/b.rkt
(module b "raquet-mlang.rkt"
  (define identity (function (x) x))
  (print (identity 5)))

Naturally, "raquet-mlang.rkt" is resolved relative to the current file, namely "/path/to/test/b.rkt", and you get the error.

In general, this is why you want to use an (absolute) module path for your expander — it works no matter where the source file is on your filesystem.

AFAICT the toy example is written this way to save the step of installing the expander module as a package. (Perhaps it shouldn’t be, if it’s unwittingly introducing a bad habit.)

@samth
Copy link
Sponsor Member

samth commented Nov 17, 2018

I think we could use define-runtime-path in syntax/module-reader to get a path that would always work.

@sorawee
Copy link
Collaborator Author

sorawee commented Apr 9, 2021

Although I understand now why it works like that, it still feels really weird as a user, especially since the reader can be required using relative path without any problem.

For anyone who stumbles upon this issue, @samth's suggestion can indeed be used as a workaround. Note that you should use #:language instead of module-path:

#lang s-exp syntax/module-reader
#:language the-expander
(require racket/runtime-path)
(define-runtime-path the-expander "../core.rkt")

Is it a good idea to mention define-runtime-path in the Racket Guide (in https://docs.racket-lang.org/guide/syntax_module-reader.html)?

@samth
Copy link
Sponsor Member

samth commented Apr 9, 2021

I think improving the example to use define-runtime-path is a good idea.

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

3 participants