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



>  - Libguile data type: scm_env_folder SCM (SCM DATA, SCM SYMBOL, SCM
>           VALUE, SCM TAIL)
>      The type of a folding function to pass to `scm_env_fold_internal'.

How do you create such a data type? 


>  - Primitive: env-undefine ENV SYMBOL

What about dropping undefine completely?  For example (define a 1)
(define (b) (display a)) (b) (undefine a) (b) returns UNDEFINED --
that's the cdr of the memoized vcell --, wich is simply wrong.

If you drop undefine and shadowing of symbols, tracking changes in
environments would be not neccesary. Thus the interface would be
much simpler.


>  - Primitive: env-set! ENV SYMBOL VALUE
>      If ENV binds SYMBOL to some location, change that location's value
>      to VALUE.  The return value is unspecified.

I don't think this is neccesary because a) in most scheme implementations
you can only access symbols `(access <module> <symbol>)' but you cannot
modify them and b) if you wan't to modify a binding, you can always obtain the
vcell and change its cdr.


>    * Environments are not required to represent variables' values using
>      value cells.  An environment is free to return `#f' in response to
>      a request for a symbol's value cell; in this case, the caller must
>      use `env-ref' and `env-set!' to manipulate the variable.

Which guile objects are *not* bound to locations?  As far as I can see
you can *always* obtain the vcell (the location) and set! its cdr, no?


>    * An environment's binding for a symbol may change.  For example,
>      the user could override an imported variable with a local
>      definition, associating a new value cell with that symbol.
[...]
> Observing Changes to Environments
> ---------------------------------

If you drop undefine and the shadowing of global variables, tracking 
environment changes would not be neccesary.  This would simplify the
interface a lot!



> Finite Environments
> -------------------
> Eval Environments
> -----------------
> Import Environments
> -------------------
> Export Environments
> -------------------

I think this boils down to three environment types plus a reference list:

eval-environment	Contains *all* module's bindings    e.g. (symbol . 99)
tag-environment		Only special bindings, tags are: static,
			read-only, friend, public    e.g. (symbol . friend)
foreign-environment	Modules are loaded "on demand", when a symbol is 
                        referenced it is cached in foreign-environment
useslist                Contains all imported modules (tag-environments)


Let me give an example:

(module-define '(package mod1))     Create a module with the above environments
                                    and a empty useslist

(export '(a))                       1.) create a symbol in eval-environment
                                        (a . <undefined>)
                                    2.) copy the symbol to a location in 
                                        tag-environment    (a . (export))
                                        Note that both `a' are the *same* 
                                        symbol. The symbol can also be found
                                        in scm_weak_symhash!
(define a 12)                       This will bind a to 12 in eval-environment


(module-define '(package mod2))     A new module, all 3 environments are empty

(module-open '((package mod1)))     Find module in global module cache and
                                    insert it into the useslist:
                                    struct module { ... SCM useslist; ...

a                                   Currently the reader tries to find this 
                                    symbolname "a".  It looks into 
                                    eval-environment, foreign-environment and
                                    then in scm_weak_symhash. 

                                    In this case it will find it in 
                                    scm_weak_symhash and returns the symbol
                                    a.

                                    It then tries to find the location it 
                                    is bound to by looking into every module 
                                    of the useslist.  After that the symbol 
                                    is copied to foreign-environment.
                                    The evaluator returns the cdr of the vcell
                                    -> 12

a                                   (Cached) 
                                    The reader looks into eval-environment,
                                    foreign-environment und returns the vcell 
                                    it has found.  The evaluator returns the
                                    cdr of the vcell -> 12

Of cause you could copy all imported symbols into the import
environment (foreign-environment) when the module is loaded and
evaluated but that would make loading of modules quite slow.


Jost