From: Bill Hogan
Subject: Re: Let/eval question
Date: 
Message-ID: <750485496.0@wyrm.rbbs-net.ORG>
>>   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)

From: Joshua Kuperman
Subject: Re: Let/eval question
Date: 
Message-ID: <kupermaj.750561198@tardis.union.edu>
··········@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
From: Dave Seaman
Subject: Re: Let/eval question
Date: 
Message-ID: <CEwIDB.GHp@mentor.cc.purdue.edu>
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
From: Tim Larkin
Subject: Re: Let/eval question
Date: 
Message-ID: <tsl1-151093111856@babyhuey.fpsnl.cornell.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
From: Ted Dunning
Subject: Re: Let/eval question
Date: 
Message-ID: <TED.93Oct15134818@lole.crl.nmsu.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.
From: CHRISTOPHER ELIOT
Subject: Re: Let/eval question
Date: 
Message-ID: <15OCT199314355456@cs.umass.edu>
>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
From: Dave Seaman
Subject: Re: Let/eval question
Date: 
Message-ID: <CEyCKB.Dqn@mentor.cc.purdue.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
From: Cyber Surfer
Subject: Re: Let/eval question
Date: 
Message-ID: <CEz7uy.M7G@cix.compulink.co.uk>
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 ---
From: Dave Seaman
Subject: Re: Let/eval question
Date: 
Message-ID: <CF01x0.Mq0@mentor.cc.purdue.edu>
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