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?


David Lutterkort <lutter@cise.ufl.edu> writes:

> Jost Boekemeier <jostobfe@calvados.zrz.TU-Berlin.DE> writes:
> 
> > 
> > > Also, with a two file system it seems like you will force a tight
> > > binding between files and modules. 
> > 
> > Yes. This is neccesary.
> > 
> 
> Why ? When you read (not load) a module definition from file, couldn't you
> split the input at define-module froms, evaluate the define-module in the
> config-environment (is that the right name ?),  switch to the module
> environment and eval the rest ? Is the problem that right now you want to
> load (i.e. read and eval) the module files rather than reading them,
> manipulating the lists you just read and then evaluate parts carefully in
  ^^^^^^^^^^^^^

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.

Instead it is better to let (define-module ..) create a new environment
and then evaluate its code in the new environment:

(eval <module-code> (make-my-mumble-env)) 


Here is an example from r5rs:

(eval '(* 7 3) (scheme-report-environment 5))
      ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    2. evaluate     1. create environment
       its code
 
These are two steps:
1. create module/environment
2. evaluate its code in the new environment

Now the next question would be: Where should we store the code that
creates the module.

1. In the module itself

Then whe have to split the module into two separate sections as shown.


2. Outside of the module

Then the function that wants to access or open the module must
do that and supply the environment it has created an an argument
to the function that evaluates the module code.

Note that this turns the module creation process upside down.
(define-module '(my mumble)) does not create a module but changes the
module's properties to the filename my/mumble.  Instead *YOU* are
the one who must create the module.  (define-module ..) can't do
this anymore.


Here's one example:

(module (ice-9 test1) ((ice-9 root)) ())
(export a b)
(protect intern)

(define a 10) 
(define (b) (display (+ a 1)) (display "\n"))
(define c 99)

(define intern 1)

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.


guile> (module-go '(ice-9 test1))            
ice-9/test1> (b)
11
ice-9/test1> (module-create '(ice-9 something))
ice-9/test1> (module-go '(ice-9 something))
ice-9/something> (module (ice-9 test1) ((ice-9 root)) ())
ERROR: You are in module ice-9/something

ice-9/something> (module (ice-9 something) ((ice-9 root) (ice-9 test1)) ())
ice-9/something> (b) ->  11   ;; from uses-list
ice-9/something> (define a (+ a 100)) (define (b) (display a))
ice-9/something> (b)  -> 110  ;; re-memoized
ice-9/something> (undefine b) (b) -> 11 ;; from useslist


This may be easier for the user but I like the two files solution
better.


> In a way, modules are several environments bundled together;

Yes.


> But modules and files have to be orthogonal concepts --- if you
> require a one-to-one (or two-to-one) association between files and
> modules, it would, for example, be impossible to write nested
> modules or several modules in a single file.

module == file + interface
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.  
A package is a directory with several modules using each others
interface and exporting protected variables to each other.

You can write all interfaces into a single file, but this is not
possible with the module code itself.  Remember that the module code
must be evaluated in its own environment.  The reader stops when it
reads a <EOF> but it can't *understand* what it reads.


> One weakness of the current module system is that the notation does not
> delimit the extent of a define-module, but rather knows when one
> define-module is done by the fact that (a) another define-module starts or
> (b) an end-of-file is encountered. This muddles the distinction between
> files and modules. I wouldn't mind a notation where the implementation of
> the module is contained inside the define-module form, just as it is for
> ordinary define's; it would be a lot cleaner.

Something like

(
  (define-module (mod one))
  (define a 12)
)
( 
  (define-module (mod two))
  (import (mod one))
)

A little bit strange, isn't it? :) 


Jost

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