>> I really ought to be able to figure this out, but can some slick genius out
>> there tell me what's going on when I evaluate the expression below?
>>
>> (let ((a 1)) (eval 'a))
>>
>> I gather from Wilensky (only reference I have) that eval can't make lexical
>> references outside the form for some reason. Why? Am I insane for thinking
>> there is some way this could return a 1? My brain feels fried.
Marshall,
My first response was, well what he has in mind is
(let ((a 1)) (eval a)), which is 1, but I would have expected the
value of (let ((anything whatever)) (eval (quote this))) to be `this'.
I was surprised to get an error (undefined symbol: this), as if I had
written (let ((anything whatever)) (eval this)), in which case I would
have expected to get the error (undefined symbol: this)! I don't see
the rationale.
Bill
a))
BILL HOGAN
* Origin: PCUG BBS - San Francisco HST/V.32 415-621-2609 (8:914/201.0)
··········@f201.n914.z8.rbbs-net.ORG (Bill Hogan) writes:
>>> I really ought to be able to figure this out, but can some slick genius out
>>> there tell me what's going on when I evaluate the expression below?
>>>
>>> (let ((a 1)) (eval 'a))
>>>
>>> I gather from Wilensky (only reference I have) that eval can't make lexical
>>> references outside the form for some reason. Why? Am I insane for thinking
>>> there is some way this could return a 1? My brain feels fried.
>Marshall,
> My first response was, well what he has in mind is
> (let ((a 1)) (eval a)), which is 1, but I would have expected the
> value of (let ((anything whatever)) (eval (quote this))) to be `this'.
> I was surprised to get an error (undefined symbol: this), as if I had
> written (let ((anything whatever)) (eval this)), in which case I would
> have expected to get the error (undefined symbol: this)! I don't see
> the rationale.
>Bill
the let does two things: establishes bindings i.e. ((a 1)) binds
1 to a.
then it eval's the body. The above is equivalent to:
(eval (eval a))
what you want is simply this or :
(let ((anything whatever)) 'this)
--
Josh Kuperman The critics say Nijinsky, the dancer
········@tardis.union.edu of course; while the punters would
probably prefer the horse.
- Elvis Costello
In article <···········@wyrm.rbbs-net.ORG>
··········@f201.n914.z8.rbbs-net.ORG (Bill Hogan) writes:
> Marshall,
> My first response was, well what he has in mind is
> (let ((a 1)) (eval a)), which is 1, but I would have expected the
> value of (let ((anything whatever)) (eval (quote this))) to be `this'.
> I was surprised to get an error (undefined symbol: this), as if I had
> written (let ((anything whatever)) (eval this)), in which case I would
> have expected to get the error (undefined symbol: this)! I don't see
> the rationale.
> Bill
Try this: (let ((anything whatever)) (eval '(+ 3 4)))
The result is 7. As with any ordinary lisp function, EVAL receives its
argument(s) already evaluated. In other words, EVAL sees the expression
(+ 3 4) (the quote was removed already before EVAL even saw the argument).
What does EVAL do with its argument? It evaluates it (again), thus
obtaining 7. Look again at what you wrote, and compare it with
(let ((anything whatever)) (eval ''this))
which has two quotes before THIS. That's what you need to avoid the
undefined symbol error, if you insist on using EVAL in this context.
--
Dave Seaman
···@seaman.cc.purdue.edu
In article <··········@mentor.cc.purdue.edu>, ···@seaman.cc.purdue.edu
(Dave Seaman) suggests
(let ((a 1)) (eval ''a))
However, this returns a, which misses the point. As I understand it, the
original question asked why we can evaluate
(let ((a 1)) (eval a))
and receive 1, or we can evaluate
(let ((a 1)) a)
and receive 1. But if we ask
(let ((a 1)) (eval 'a))
we get an undefined symbol error. The questioner thought that in this
scope, (quote a) should evaluate to a (before eval sees it), so that
(let ((a 1)) (eval 'a))
should be equivalent to
(let ((a 1)) (eval a))
which returns 1. In short, why isn't (eval 'a) equivalent to a?
--
tim larkin
····@cornell.edu
In article <·················@babyhuey.fpsnl.cornell.edu> ····@cornell.edu (Tim Larkin) writes:
which returns 1. In short, why isn't (eval 'a) equivalent to a?
because in many lisps, eval uses a null lexical scope and can thus
only access global variables.
>However, this returns a, which misses the point. As I understand it, the
>original question asked why we can evaluate
> (let ((a 1)) (eval a))
> and receive 1,
You could trace EVAL to see what is happening above. "a" is evaluated
first (starting from the most deeply nested form) and the result is 1,
which is passed to EVAL. The number 1 evaluates to itself, so this
is the final result.
>or we can evaluate
>(let ((a 1)) a)
>and receive 1.
This is the same as above, but the number 1 is never evaluated.
However, since number evaluate to themselves this gives an identical
result.
>But if we ask
>
>(let ((a 1)) (eval 'a))
>we get an undefined symbol error. The questioner thought that in this
>scope, (quote a) should evaluate to a (before eval sees it), so that
Exactly right, since (eval 'a) will always use the global binding
for "a", never the lexical binding.
Think about this form:
(let ((var 'a)) ;This is outside the lexical scope in whihc "a" is bound.
(let ((a 'one)) ; Create lexical binding for "a"
(eval var)))
If you trace EVAL while evaluating this you see that its argument is
the same as above. But there is no way to access the lexical binding
of "a" at this point.
Consider this:
(defun foo (x)
(eval x))
The EVAL in foo is certainly not in this lexical context:
(defun bar (var)
(let ((a 'one))
(foo var)))
When BAR is compiled the lexical variable "a" is turned into a
reference to some relative stack location. So we look at this:
(let ((var 'a))
(bar var))
Now we see that the EVAL in FOO called from BAR clearly has
no way to access the lexical binding of "a". Got it?
Chris Eliot
>(let ((a 1)) (eval 'a))
>
>should be equivalent to
>
>(let ((a 1)) (eval a))
>
>which returns 1. In short, why isn't (eval 'a) equivalent to a?
>--
>tim larkin
>····@cornell.edu
In article <·················@babyhuey.fpsnl.cornell.edu> ····@cornell.edu
(Tim Larkin) writes:
> In article <··········@mentor.cc.purdue.edu>, ···@seaman.cc.purdue.edu
> (Dave Seaman) suggests
>
> (let ((a 1)) (eval ''a))
[...]
>
> But if we ask
>
> (let ((a 1)) (eval 'a))
>
> we get an undefined symbol error. The questioner thought that in this
> scope, (quote a) should evaluate to a (before eval sees it), so that
It's because a was not declared special. I thought that point had already
been answered, which is why I didn't mention it. Try the following:
>(let ((a 1)) (eval 'a))
Error: The variable A is unbound.
>(defvar a 3)
A
>(let ((a 1)) (eval 'a))
1
>a
3
--
Dave Seaman
···@seaman.cc.purdue.edu
In article <··········@mentor.cc.purdue.edu>,
···@seaman.cc.purdue.edu (Dave Seaman) writes:
> (let ((anything whatever)) (eval ''this))
>
> which has two quotes before THIS. That's what you need to av
> undefined symbol error, if you insist on using EVAL in this
What would happen if the variable was declared special?
Would eval still not see it?
Martin Rodgers
--- Cyber Surfing on CIX ---
In article <··········@cix.compulink.co.uk> ············@cix.compulink.co.uk ("Cyber Surfer") writes:
>In article <··········@mentor.cc.purdue.edu>,
>···@seaman.cc.purdue.edu (Dave Seaman) writes:
>
>> (let ((anything whatever)) (eval ''this))
>>
>> which has two quotes before THIS. That's what you need to av
>> undefined symbol error, if you insist on using EVAL in this
>
>What would happen if the variable was declared special?
>Would eval still not see it?
A variable may be declared special and still not have a global
binding. In that case, you would still get an undefined symbol
error.
If THIS has a global binding, even if THIS is not declared special,
the expression
(let ((anything whatever)) (eval 'this)) ; only one quote
will find the global binding for THIS. What is more interesting is what happens
if THIS is assigned a value in the LET clause. Consider the following sequence:
Welcome to Macintosh Common Lisp Version 2.0p2!
? (setf x 'y)
Y
? (let ((x 'z)) (eval 'x))
;Compiler warnings :
; Unused lexical variable X, in an anonymous lambda form.
Y
? (declaim (special x))
NIL
? (let ((x 'z)) (eval 'x))
Z
? x
Y
?
The reason there can be a compiler warning in the middle of an
interactive session is that MCL compiles everything on the spot as
you type it. The significant thing about what the compiler warning
says is that there are two different variables in that expression,
both named X. One of them is a lexical variable, which is defined
but not used, and the other is a free variable, which is used but
not defined within the expression. After X is made special, the
exact same expression is compiled and executed with no warnings,
but with a different result. Both occurrences of X in the second
expression are references to the global X, and the expression
therefore evaluates to Z instead of Y.
--
Dave Seaman
···@seaman.cc.purdue.edu