One of the first issues I had when evaluating scheme as a possible replacement for Python as my hobby language was its apparent lack of module/library/namespace system. How do people possibly build big programs? I wondered.
Now it turns out most (all?) scheme implementations have features to deal with modules and libraries. Gambit's is particularly nebulous in that it doesn't appear to be documented anywhere. Anyway, here's how it appears to work. I'm sure somebody will correct me if I've got something wrong:
Gambit has the 'namespace' primitive, with which you can declare that certain definitions belong in certain namespaces. Here's an example:
> (namespace ("f#" foo) ("b#" bar baz))
This means (AFAICS): "any further use/definition of the term 'foo' will reference the f# namespace and any use of bah/baz will reference the b# namespace".
> (namespace ("f#" foo) ("b#" bar baz)) > (define (foo) "I am foo") ; defines f#foo > (foo) "I am foo" > (f#foo) "I am foo" > (define (bar) "I am bar") > (b#bar) "I am bar"
This is cool because it allows you to retroactively fit namespaces to scheme code loaded from other files. E.g. If mod1.scm and mod2.scm both defined a procedure 'foo', you could use namespaces to allow both to be used in the same environment thus:
> (namespace ("m1#" foo)) > (load "mod1") ; contains: (define (foo) "I am mod1's foo") > (namespace ("m2#" foo)) > (load "mod2") ; contains: (define (foo) "I am mod2's foo") > (m1#foo) "I am mod1's foo" > (m2#foo) "I am mod2's foo"
Job done. Now I haven't really used gambit namespaces much, so I not in a position to provide a good comparison with other approaches, however the feature does seem in keeping with the rest of the scheme language. By that I mean rather than a large set of fully blown rich language features you get a small bunch of simple but very extensible primitives with which to build your own language.
An good example of building a big system over these small primitives is Christian Jaeger's chjmodule library where he has used namespaces along with 'load' and 'compile-file' (and of course macros) to build a more industrial strength module system. This includes an 'import' keyword that loads from a search path and a procedure to recursively compile and import modules. Some example code from the README:
$ gsc -i -e '(load "chjmodule")' - > (import 'srfi-1) > fold #<procedure #2 srfi-1#fold> > (fold + 0 '(1 2 3)) 6 > (build-recursively/import 'regex-case) ; recompiles regex.scm (a dependency) if necessary, ; then (re)compiles regex-case.scm if necessary and imports it. > (regex-case "http://www.xxx.yy" ("http://(.+)" (_ url) url) (else url)) "www.xxx.yy" > *module-search-path* ("." "mod" "gambit" "~/gambit" "~~" "..")
Sweet. I'm guessing it'll also be possible to build the r6rs library syntax in gambit scheme the same way.