lexi-lambda / racket-r7rs

An implementation of R7RS in Racket
97 stars 14 forks source link

import search path #10

Closed amirouche closed 5 years ago

amirouche commented 5 years ago

I am trying to create a template project to test a module across scheme implementations. I tried to make it work with racket-r7rs but I fail to import some module even if is included in the search path with --search option.

Here is an example run:

$ cat tests/version.racket.scm 
#lang r7rs
(import (scheme base)
        (tests helpers)
    (nstore))

(include "version.scm")
$ cat src/nstore.rkt 
#lang r7rs
(define-library (nstore)

  (export nstore-version)
  (import (scheme base))

  (begin

    (include "nstore.scm")))
$ ~/racket/bin/racket --search src/ --search . --script tests/version.racket.scm 
standard-module-name-resolver: collection not found
  for module path: nstore
  collection: "nstore"
  in collection directories:
   /home/amirouche/.racket/7.2/collects
   /home/amirouche/racket/collects
   /home/amirouche/src/scheme/nstore/src/
   /home/amirouche/src/scheme/nstore/
   ... [162 additional linked and package directories]
  context...:
   show-collection-err
   standard-module-name-resolver
   perform-require!78
   for-loop
   finish
   [repeats 3 more times]
   pass-1-and-2-loop
   module-begin-k
   expand-module16
   expand-capturing-lifts
   temp118_0
   temp91_0
   compile15
   temp85_0
   loop
lexi-lambda commented 5 years ago

R7RS does not specify anything about how module paths are mapped to files on the filesystem, so you cannot portably import any module that isn’t defined by the standard. It’s just not standardized. Sorry.

This particular implementation maps R7RS module paths to Racket module paths by transforming paths like (foo bar baz) to foo/bar/baz, which means that if R7RS code is installed as a Racket package using raco pkg, then its constituent modules will be indexed in the global namespace of module paths (as with any other package), and such imports will be able to work. But there is no mechanism for relative imports.

The --search option to Racket is technically another way to make that happen, too, but you’re still at the mercy of Racket’s module name resolver. For example, the default module name resolver maps a module path foo to <collects>/foo/main.rkt, not <collects>/foo.rkt, so your (import (nstore)) will go looking for <collects>/nstore/main.rkt.

If you want, you can obviously arrange for that file to exist, but again, being generally portable is impossible, as the standard says nothing about any of this. I don’t even really make any guarantees that this package won’t change its module name resolution algorithm in the future, since the only guarantee is that this package will be compliant with the standard.

rain-1 commented 5 years ago

Perhaps we could settle on an ad-hoc standard for how this particular R7RS implementation does module resolution. Even if it's just a mirror of rackets approach.

amirouche commented 5 years ago

The current way of resolving modules works for me.

(what I am missing is r7rs red edition modules, but that is another story)

lexi-lambda commented 5 years ago

(what I am missing is r7rs red edition modules, but that is another story)

Get back to me when R7RS large is completed, and maybe I’ll take a look. But I’m not touching an unfinished standard.