Following my experiment converting the "futures" Chicken egg using Gambit's namespace mechanism, I have come up with a pretty minimal set of special forms to do the same thing but more elegantly, namely:
;; (##module <module-name> <language-name> ;; (export <id> ...) ... ;; (define-macro ...) ... ;; ) ;; ;; (##require <module-name>) ;; ;; Currently, <module-name> must be a symbol naming the source file ;; without the extension and <language-name> must be the symbol ;; |gambit|. ;; ;; The ##module form must be the first expression in a file and ;; the ##require form can appear anywhere a definition can appear.
I'm attaching the code to this message. Please give it a try and let me know what you think. This is really just a strawman whose purpose is to elicit a discussion on this approach.
You can start the "pfib.scm" example with:
% gsi -e '(include "modules.scm")' pfib
The futures module is no longer split into two files (as it is in Chicken). It is a single file containing the compile and run time parts. It looks like this:
;;; File: "futures.scm"
(##module futures gambit
(export future touch)
(define-macro (future exp) `(futures##make-future (lambda () ,exp))))
(define-type placeholder results condition failed? complete? thread)
(define (make-future thunk) ...)
(define (touch x) ...)
As you can see the ##module form at the top of the file contains all the compile-time information that is needed by a (##require futures). The macro "future" expands into a call to futures##make-future, which is a private function of the module (it is not exported). That's why it contains two sharp signs. The body of the module or macros could contain ##require forms, such as (##require srfi-18).
Marc