This is the mail archive of the guile@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: Where should guile modules store meta data?


Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes:

> 
> That is exactly the problem: you have to manipulate the environment
> in place.  Something like that:
> 
> (define-module (my mumble))      ; evaluates to 
>                                  ; (set! the-environment (make-my-mumble-env))
>                                       ^^^^^^^^^^^^^^^^^^^^^^^
>                                  ; now evaluate all expr. in the new env:
> (define a 12)                    ; (environment-define the-environment 'a 12)
> a -> 12                          ; (environment-ref the-environment 'a)
> 
> 
> When you do this, you can't use multiple REPL's at the same time without
> worrying about their state.  Try to implement a (go-module <module>)
> in the old module-system and you'll see what I mean.
> 

I'm not sure that I understand the go-module issue, but it seems that the
problem is that the current module system keeps all its state in global
variables, a consequence of the current syntax. The syntax that I talked
about in an earlier post would also resolve some of your implementation
problems, since you know exactly which code needs to be evaluated inside
the new module. I mean something like

(defmacro* define-module (name #&key import export . rest)
  (let ((body (remove-keywords rest)))
    `(let ((new-module (make-new-module)))
	(register-module ',name new-module) 
	(module-resolve-imports new-module ',import)
	(module-make-public-interface new-module ',export)
	(eval (begin ,@body) (module-eval-environment new-module))
	new-module)))

which doesn't need any global variables (well, except for some kind of
registry for the modules loaded into the system). This syntax has a lot of
advantages over the old one. For one, it uses lexical scope, just like the
rest of Scheme, to determine where definitions go, not dynamic scope as the
old module system does. There are two big drawbacks, though:

(1) We need a special define-module if we are in the repl since the user
    expects that each of the BODY forms is evaluated as soon as she types
    them in. But how important is it to type modules in interactively ?
    Unless you're testing the module system, you're probably not very
    interested in keeping your namespace in the repl nice and tidy with
    lots of modules ...

(2) It is incompatible with the existing module system: this might be the
    biggest obstacle, since it requires to make (trivial) changes to every
    existing module. This is probably the toughest issue since it requires
    that most people agree that they will benefit from this change.

> If you go to the module ice-9/test, the function (module-go '(ice-9 test))
> creates a new module and evaluates the module code in this module.

What is the purpose of module-go ? If you're not concerned about instant
gratification in the repl, you could change it to (module-go <module>
. <body>) which would evaluate <body> within <module>.

> module == file + interface

There is no concept 'file' in Scheme as a programming language. The only
reason that there is often a one-to-one correspondence between files and
modules is that both the filesystem and modules use a hierarchical
namespace and it is very convenient and simple to map one namespace into
the other. 

> It is (and should) be impossible to write several modules in a single
> file.  And you can't nest modules either (in the strict sense).  But
> you can bundle them into a package.  A collection of modules 
> together in a single file is not a package.  

Here's one reason why it is good to have several modules in one file: I
write a fairly large script that becomes much clearer if I split it up into
several modules. When I distribute the script to others, I don't want them
to have to put several files in some module-directory and the main script
in their bin dir. It's much easier for them to just put one file into their
bin dir.

I don't see what's wrong with nesting modules. Package is just another name
for a module whose public interface exports nothing but other modules. How
modules and packages are stored (files/directories/one big jar file) is an
implementation issue which has no bearing on the concept of module.

> A package is a directory with several modules using each others
> interface and exporting protected variables to each other.

Ahhh, yes, there is something you couldn't do with the module system I was
thinking about: having two interfaces for the same module (one to be
exported outside the package and one for your brethren within a
package). You could simulate it by sticking all package private things into
a module that is not exported by the package, but accessible within the
package; but that's pretty ugly.

It seems that a decision needs to be made first about what features the new
module system should provide, or if we just want to stick with the old
high-level module system. I would really like to see an import-renaming
facility added to the current module system ....

David

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