Mark H Weaver <m...@netris.org> writes: > David Kastrup <d...@gnu.org> writes: >> I am still fuzzy on what local-eval will do when the current module at >> the time of the-environment is different from that at the time of >> local-eval. > > (the-environment) saves the module (where it is textually located) in
What does "where it is textually located" mean? > the lexical environment object. If (the-environment) was passed to > `eval', that's the module specified by `eval's second parameter. > > If (the-environment) was passed to `primitive-eval', then that's the > (current-module) at the time primitive-eval was called. > > `local-eval' passes the saved module to `eval', which temporarily > restores it (using dynamic-wind) as the current module during both > macro expansion and evaluation of the local expression. > `local-compile' passes the saved module as the #:env parameter to > `compile', which has the same effect as for `local-eval'. >> since the current module, even if nominally the same, can contain >> different variables at the time of local-eval, my take on that would >> be to not make it part of the environment at all. That is, >> everything that is not reachable through local scopes is not part of >> the environment. > > I heartily disagree. A module is conceptually part of every lexical > environment evaluated within that module. What does "evaluated within a module" mean? For me, a module provides the fallback for everything that can't be resolved at local scope. Basically, it is relevant for everything that "tops out" at top level. Now the point of local-eval is that we are evaluating in a different context than the original one. As opposed to the variables bound in any given lexical scope defined by its source positions, the module-level bindings are non-constant and can change between the-environment and local-eval. So they are not quite at the same level. > That this makes sense is particularly evident in the case of > recursively defined top-level procedures. For example, in > > (define (factorial n) > (if (zero? n) 1 (* n (factorial (- n 1))))) > > it would be crazy for any lexical variable "search path" starting from > within the definition of `factorial' to lead anywhere other than the > module where this definition was evaluated, i.e. where the top-level > `factorial' was bound. (define (factorial n) (if (zero? n) 1 (* n (factorial (- n 1))))) (eval `(,factorial 5) (resolve-module '(none))) This works actually fine since apparently the "factorial" inside of the function is bound to the actual variable of the module. It is _not_ bound to the _value_ of the variable: if you subsequently redefine factorial while saving a copy, calling the copy will in the recursion call the redefinition. However, I would have expected if I now do (define sob factorial) (module-remove! (current-module) factorial) that the variable gets removed from the module but stays operative. It turns out that this is not the case: guile> (define sob factorial) guile> (module-remove! (current-module) 'factorial) #f guile> (factorial 3) Backtrace: In current input: 25: 0* (factorial 3) <unnamed port>:25:1: In expression (factorial 3): <unnamed port>:25:1: Unbound variable: factorial ABORT: (unbound-variable) guile> (sob 3) Backtrace: In current input: 26: 0* [factorial 3] 22: 1 (if (zero? n) 1 (* n (factorial (- n 1)))) 22: 2 [* 3 ... 22: 3* (factorial (- n 1)) <unnamed port>:22:24: In expression (factorial (- n 1)): <unnamed port>:22:24: Unbound variable: factorial ABORT: (unbound-variable) guile> (define factorial 'huh) guile> (sob 3) Backtrace: In current input: 28: 0* [factorial 3] 22: 1 (if (zero? n) 1 (* n (factorial (- n 1)))) 22: 2 [* 3 ... 22: 3* [huh 2] <unnamed port>:22:24: In expression (factorial (- n 1)): <unnamed port>:22:24: Wrong type to apply: huh ABORT: (misc-error) guile> So I am somewhat fuzzy on what is supposed to work here how. -- David Kastrup