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] |
> - 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