This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: nested modules / anonymous modules



> Is there any spec for the proposed module system?  All I've ever seen
> is Jim Blandy's low level environment spec. 

Jim's first level environments are written and the module code now uses 
environments instead of first class variables.  From the users point of
view nothing has changed.


> Rscheme, MIT Scheme, Blume's, Tung's, Lee and Friedman's, Curtis and
> Rauen's, Bigloo, &c)?  Scheme module systems have existed for years so
> there is not need for guile to re-invent old ideas.

I think we can pretty much forget about the module systems used by 
Bigloo, Rscheme and MIT Scheme (althought I've stolen some ideas from these
implementations :>).

I am aware of Jonathan Rees' and Matthias Blume's work but I can't say anything
about module systems designed by Mr. Tung, Lee, Friedman, Curtis or Rauen.  
(What is "&c" btw?)


[(set! *the-module* (make-module ...)]
Jost> This solution uses a single global variable to switch from
Jost> one module to another.  Which means that only one module at
Jost> a time can exist.
> In what sense can only one module exist at a time?

Even if guile will stay single threaded, modules must carry
information about their state.

For example when you open module M the code is loaded into guile's
address space and a continuation for M is created.  If you want to
compile M, you must close it first and write the module back onto disc.

It is certainly possible to use only one continuation for all modules
and to use a global variable to switch between them.  But even in a
single threaded environment this solution has some problems.  For
example if you load a piece of code you may find yourself in a
differend module than you've expected, especially when the code itself
loads other code and "forgets" to restore the global state variable.

That's why the implementation uses exactly one continuation for an
opened module (closed modules don't have a continuation and are marked
as textually closed).


Jost> 4.  One file -- one module
> This has the advantage of being C-like so it's easy for C-philes to
> grok.  

Java like. :)  

The reason why I like this attempt is backwards compatibility.  You can treat old
slib files as modules. For example the following files "test1/2.scm" are modules
and have separate name spaces.

$ cat test.scm
(require ...) 
(define a ...)

$cat test2.scm
(define m (module-access (ice-9 test)))
(define a (+ (module-ref m a) 1)


What the above examples don't provide are private symbols.  All
symbols are exported from modules test.scm and test2.scm.

If you want to export only certain symbols you can rewrite test.scm
as follows:

$ cat test.scm
(require ...)
(module-export a b c)
(define a ...)


or:

$ cat test.scm
(module (ice-9 test)
	(open ...) ;; instead of require
	(export a b c))
(define a ...)


Note that (module (ice-9 test) (open <open-list>) (export <export-list>)) is 
rewritten to:

;; check if we are really in module (ice-9 test)
(if (not (eq (the-module) (module-access (ice-9 test))))
	(error "Module declaration and module definition do not match"))
(module-open <open-list>)
(module-export <export-list>)


Do you see the trick?  (module (ice-9 test)) is evaluated *in* the
module (ice-9 test).  When the module declaration is evaluated the
module is already there.  That's why you can write the module
declaration (module ...) at the beginning or at the end of the file or
you can even leave it out and use (module-open ...) and (module-export
...)  anywhere within the module.


In contrast:
(define-structure	(ice-9 test) 
			(open <open-list>)
			(export <export-list>)
			(begin <program code>))

<program code> is evaluated in an environment created
by (define-structure ...) and the (define-structure ...) definition is
evaluated in the config module (the "meta module" which
holds all module signatures).


I really think that the module declaration (module ...) is easier to
use that Jonathan's static module definition.  If you develop a new
module you start emacs, open a file and evaluate that module as often
as you want.  You don't have to step into the meta module (,in config
in scheme48) to modify the interface.  Just use export and open when
you need to export and import symbols. The (module ...) declaration is
more convenient when you want to publish the module but since it is 
internally rewritten into open and export clauses anyway you don't
have to use it. 


> Why?  I don't see any problem with compiling a file which contains
> more than one module.  

Not really a problem but what how should the following be compiled:

;; in file ice-9 test
(define-module (ice-9 test))
(define-module (ice-9 test1))
(define-module (ice-9 test2) :use-module (ice-9 test1))

;; in file ice-9 my-test
(define-module (ice-9 my-test))
(define-module (ice-9 test1))
(define-module (ice-9 test2) :use-module (ice-9 test1))



Jost

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]