eliot@phoenix.Princeton.EDU (Eliot Handelman) (10/28/88)
In article <249@pitstop.UUCP> robv@pitstop.UUCP (Rob Vollum) writes: >Of course, there are the other problems, such as EVAL not being >able to "see" lexical variables, etc. Is that really true? In the following example, EVAL consults the lexical environment, rather that the global. (setq x nil) And now (let* ((x t) (y x)) (eval y)) => t The result of the first evalution sets y to x; yet EVAL gets the effective lexical binding anyway. This also seems to work whether or not the code is compiled and x is made special. Can you give an example where that isn't the case? Eliot Handelman Music, Princeton U.
andreasg@boulder.Colorado.EDU (Andreas Girgensohn) (10/28/88)
In article <4154@phoenix.Princeton.EDU> eliot@phoenix.Princeton.EDU (Eliot Handelman) writes: >Is that really true? In the following example, EVAL consults the lexical >environment, rather that the global. > >(setq x nil) > >And now (let* ((x t) (y x)) (eval y)) => t EVAL evaluates its argument so that the above call of eval is the same as (eval 't). (eval 'y) will lead to an error unless y is a special variable. Andreas Girgensohn andreasg@boulder.colorado.edu
duff@eraserhead (David A Duff) (10/29/88)
In article <4154@phoenix.Princeton.EDU>, eliot@phoenix (Eliot Handelman) writes: >In article <249@pitstop.UUCP> robv@pitstop.UUCP (Rob Vollum) writes: [... stuff about eval only being able to perform evaluation in the top-level environment.] >Is that really true? In the following example, EVAL consults the lexical >environment, rather that the global. Yes. >(setq x nil) >And now (let* ((x t) (y x)) (eval y)) => t Remember: eval is a function, and the semantics of lisp are such that when evaluating a function application (a list whose car is neither a macro nor a special form), the arguments are evaluated first, then the function is applied. So, basically, whatever you put in place of ... in "(eval ...)" ends up getting evaluated TWICE -- once before eval is called and once after. In your example above, the eval function never sees the symbol y, but is instead passed the value t. To better illustrate the difference between evaluation within a lexical environment and evaluation in the top-level environment (the kind that the lisp eval function does) you probably meant to try something like this: (setq x nil) ;; here x is eval'd in lexical environment: (let ((x t)) x) ==> t ;; here x is eval'd in top-level environment: (let ((x t)) (eval 'x)) ==> nil Dave Duff GE Research and Development Center duff@eraserhead.steinmetz.ge.com Schenectady, New York uunet!steinmetz!eraserhead!duff 518-387-5649 Dave Duff GE Research and Development Center duff@eraserhead.steinmetz.ge.com Schenectady, New York uunet!steinmetz!eraserhead!duff 518-387-5649
robv@pitstop.UUCP (Rob Vollum) (11/02/88)
In article <4154@phoenix.Princeton.EDU> eliot@phoenix.Princeton.EDU (Eliot Handelman) writes: >In article <249@pitstop.UUCP> robv@pitstop.UUCP (Rob Vollum) writes: > >>Of course, there are the other problems, such as EVAL not being >>able to "see" lexical variables, etc. > >Is that really true? In the following example, EVAL consults the lexical >environment, rather that the global. > >(setq x nil) >And now (let* ((x t) (y x)) (eval y)) => t > >The result of the first evalution sets y to x; yet EVAL gets the effective >lexical binding anyway. This also seems to work whether or not the code is >compiled and x is made special. Can you give an example where that >isn't the case? > >Eliot Handelman In the example given above, you're not really EVALing a symbol; you're EVALing the value of a symbol. Things worked out (in this case) because T is self-evaluating. If you had tried (let* ((x 'a) (y x)) (eval y)) you would have gotten an error along the lines of "symbol A has no global value..." To illustrate the point that EVAL cannot see the lexical environment, try this: (setq x 'global-value) (let ((x 'lexical-value)) (eval 'x)) --> GLOBAL-VALUE (and remember, the initial SETQ *must* be a SETQ, and not a DEFVAR, since DEFVAR proclaims things SPECIAL, after which they can never be lexical.) As to why EVAL might be specified not to see lexical values of symbols: compilers don't deal with symbol names when accessing lexical variables, generally. They deal only in stack offsets. In fact, in your example above, what's happening is somewhere along the following lines: the compiler creates two slots on the stack; one for x, one for y. When compiling the code for the "eval" expression, it generates something like "load the contents of stack-pointer+2". It never mentions Y at all. So, when EVALing symbols at run-time, the system really has no choice but to grab the top-level value. Rob Vollum UUCP: ...sun!sunne!robv ARPA: rvollum@sun.com