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: First-class environment proposal


Hi,

>    Guile distinguishes between environments and modules.  A module is a
> unit of code sharing; it has a name, like `(math random)', an
> implementation (e.g., Scheme source code, a dynamically linked library,
> or a set of primitives built into Guile), and finally, an environment
> containing the definitions which the module exports for its users.

/* a module consists of the following elements */
#define SCM_MODULE_OBARRAY(mod) (SCM_VELTS (mod)[0])
#define SCM_MODULE_USESLIST(mod) (SCM_VELTS (mod)[1])
#define SCM_MODULE_REFLIST(mod) (SCM_VELTS (mod)[2])
#define SCM_MODULE_FRIEND_OBARRAY(mod) (SCM_VELTS (mod) [3])
#define SCM_MODULE_PUBLIC_OBARRAY(mod) (SCM_VELTS (mod) [4])
#define SCM_MODULE_FOREIGN_OBARRAY(mod) (SCM_VELTS (mod) [5])
#define SCM_MODULE_PACKAGE(mod) (SCM_VELTS (mod) [6]) /* back pointer */
#define SCM_MODULE_TIMESTAMP(mod) (SCM_VELTS (mod) [7])


>    An environment, by contrast, is simply an abstract data type
> representing a mapping from symbols onto variables which the Guile
> interpreter uses to look up top-level definitions.  The `eval'
> procedure interprets its first argument, an expression, in the context
> of its second argument, an environment.

Hmm. I donīt see why the environment should be an abstract data type and visible
to the user.  But anyway:

SCM_CEVAL (x, env, module)
     SCM x;
     SCM env;
     SCM module;
{
  SCM new_module = module;
[...]
	case scm_tcs_closures:
	clos1:
	  x = SCM_CODE (proc);
	  module = SCM_MOD (proc); /*!*/

-------------------- test:
guile> (module-define 'jost/test1)
guile> (export '(access-it count))
guile> (define (count) (set! private (+ private 1)))
guile> (define private 0)
guile> (define (access-it) private)

guile> (module-define 'peter/test1)
guile> (module-open '(jost/test1))
guile> (define private 12)
guile> private
12
guile> (count)
guile> (access-it)
1
guile> private
12
guile> (count)
guile> (access-it)
2


guile> ; try to overload (access-it)
(define (access-it) (private))
ERROR: can't shadow foreign symbol. 
ABORT: (misc-error)

Currently re-export doesn't work... :)


>   Guile uses environments to implement its module system. 

Umm, at the moment the "environment" is just an obarray associated with a module. Thats all.
The implementation uses a "foreign_obarray" for caching (exported symbols go there) and two
other obarray's where symbols are looked up that may or may not be visible to others (public
and package ("friend") protection).


> A module
> created by loading Scheme code might be built from several environments.

I don't unterstand that statement.  Are you talking about packages?

guile> (module-define 'my-package/test1)
guile> (friend '(protected-var))
guile> (define protected-var 1)
guile> (module-define 'my-package/test2)
guile> (module-open '(my-package/test1))
guile> protected-var
1
guile> (module-define 'your-package/test2)
guile> (module-open '(my-package/test1))
guile> protected-var
ERROR: Unbound variable: protected-var
ABORT: (misc-error)
guile> 


> closes over

Yes and no.  I just would not use the term "close over" here.  :)


> Without changing the interpreter, you
> can implement any module system you like, as long as its efforts produce
> an environment object the interpreter can consult.

Hmm, I still don't understand why guile should support more than one module system!?!



Jost