Path: utzoo!attcan!uunet!seismo!sundc!pitstop!robv From: robv@pitstop.UUCP (Rob Vollum) Newsgroups: comp.lang.lisp Subject: Re: Scope of EVAL (was: Re: Summing a list) Message-ID: <254@pitstop.UUCP> Date: 1 Nov 88 18:47:37 GMT References: <10794@srcsip.UUCP> <10813@srcsip.UUCP> <249@pitstop.UUCP> <4154@phoenix.Princeton.EDU> Reply-To: robv@pitstop.UUCP (Rob Vollum) Organization: Sun Microsystems, Inc., Lexington, MA Lines: 45 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