[comp.lang.lisp] EVAL with environment

endelman%wellworld@Sun.COM (Aaron Endelman) (08/08/88)

In article <24909@think.UUCP> barmar@kulla.think.com.UUCP (Barry Margolin) writes:
>In article <5071@zodiac.UUCP> yushen@ads.com (Yu-shen Ng) writes:
>>How can I do an "eval" within the lexical scope from which the "eval" is called?
>
>You can't.  EVAL is an ordinary function, so it has no idea what
>lexical context it was called in (only special forms and macros can
>access the lexical context).
>
>How would it possibly work in a compiled function, when references to
>lexical variables have been converted to stack frame offsets, and the
>names of the local variables have been discarded?  If the Lisp
>implementation saves the local variable information (as it does on
>Lisp Machines) then there will likely be an implementation-specific
>function for evaluating in a given lexical environment (for use by the
>debugger, for instance); a common mechanism is to allow EVAL to take
>an optional second argument, which is the lexical environment.
>However, Common Lisp doesn't require this capability.
>
>Why do you need this capability?  If the form you want to evaluate is
>coming from outside the function, how could it possibly know the names
>of your local variables?
>
>Perhaps you should describe what you are trying to accomplish, since I
>suspect you may be going about it wrong.  It is almost always wrong to
>call EVAL explicitly from a function.  You can usually do what you
>want with FUNCALL or APPLY.

I'd like to put in a plug for this capability, too.  I'd like to see eval
take an optional environment arg as part of the CL standard.  Sometimes
there's a real need to be able to generate interpreted code on the fly which
retains lexical context.  As things stand, let's say I programmatically
generate a function foo which then invokes a previously-compiled macro bar:

(defun foo (x)     ; interpreted
   (bar x))

(defmacro bar (y)  ; compiled
  `(progn 
     (...some big hairy form, possibly invoking more macros...)
     ,y))

So (foo 'a) => a

Postulate also that I don't want to compile foo because the implicit
macroexpansion of bar at that time would send me to the coffee machine.

The problem is avoiding all the overhead involved in macroexpanding bar's
body at run time.  What I'd like is:

(defun foo (x)     ; interpreted
  (eval '(bar x) *current-environment*))

(defun bar (y)     ; compiled
  (...some big hairy form...)
  y)

------------------------------------------------------------------------
Gillian:  Sure you won't change your mind?
Spock: Is there something wrong with the one I have?

Aaron Endelman                                  endelman@sun.com
Symbolic Programming Group                      ...!sun!endelman
Software Products Division
Sun Microsystems, Inc.
------------------------------------------------------------------------