Can anybody explain me how eval works with emacs24? From eval description:
eval is a built-in function in `C source code'.
(eval FORM &optional LEXICAL)
Evaluate FORM and return its value.
If LEXICAL is t, evaluate using lexical scoping.
Does that mean, that something like this should work?
(setq lexical-binding t)
(let ((myvarr 42)) (eval 'myvarr t)) ; (void-variable myvarr)
Update:
(setq lexical-binding nil)
;; => nil
(let ((myvarr 42)) (eval 'myvarr))
;; => 42 (#o52, #x2a, ?*)
(setq lexical-binding t)
;; => t
(let ((myvarr 42)) (eval 'myvarr))
;; Debugger entered--Lisp error: (void-variable myvarr)
;; eval(myvarr)
;; (let ((myvarr 42)) (eval (quote myvarr)))
;; (progn (let ((myvarr 42)) (eval (quote myvarr))))
;; eval((progn (let ((myvarr 42)) (eval (quote myvarr)))) t)
;; eval-last-sexp-1((4))
;; eval-last-sexp((4))
;; call-interactively(eval-last-sexp nil nil)
;; call-last-kbd-macro(nil kmacro-loop-setup-function)
;; kmacro-call-macro(nil nil)
;; kmacro-end-or-call-macro(nil)
;; call-interactively(kmacro-end-or-call-macro nil nil)
(ignore-errors (let ((myvarr 42)) (eval 'myvarr)))
;; => nil
(setq lexical-binding nil)
;; => nil
(eval (let ((myvarr 42)) (eval 'myvarr)) t)
;; => 42
(eval '(let ((myvarr 42)) (eval 'myvarr)) t)
;; Debugger entered--Lisp error: (void-variable myvarr)
;; eval(myvarr)
;; (let ((myvarr 42)) (eval (quote myvarr)))
;; eval((let ((myvarr 42)) (eval (quote myvarr))) t)
;; eval((eval (quote (let ((myvarr 42)) (eval (quote myvarr)))) t) nil)
;; eval-last-sexp-1((4))
;; eval-last-sexp((4))
;; call-interactively(eval-last-sexp nil nil)
Emacs version: GNU Emacs 24.1.1 (i386-mingw-nt6.1.7600) of 2012-06-10 on MARVIN
Since lexical binding breaks much existing elisp code, it is an opt-in feature.
lexical scoping can best be understood with a simple example:
(defun some-func (callback)
(let ((a 5))
(funcall callback)))
(let ((a 3))
(some-func (lambda () a)))
Under most languages, this would return 3 since the a in some-func doesn't seem visible from the bottom form. However, in emacs before 24 or without lexical scope this program returns 5.
This has led to many unexpected surprises and subtle and often hidden bugs between interacting functions; to fix this emacs 24 introduced lexical scoping, but as mentioned previously, is backwards compatible.
The mechanism to opt-in to dynamic scoping is either the file variable lexical-binding (which turns it on per source file) or as the option you see to eval
So if we rewrite the example to use eval:
(eval '(let ((a 3))
(some-func (lambda () a))) nil) ; => 5
(eval '(let ((a 3))
(some-func (lambda () a))) t) ; => 3
In your example, what is making the difference is not whether the code inside eval is dynamically scoped, but whether the code surrounding it is. Variable binding is what is affected by lexical scoping, not variable lookup. I'm not completely certain of eval's semantics here, but what seems to be happening (and what makes the most sense) is eval evaluates the expression in an entirely new lexical context. So the outer lexical scope is hidden from the inside of eval, but the dynamic scope is still visible (so the lookup succeeds when the file is dynamically scoped, but not otherwise).
I could not find the formal semantics of the eval function in Emacs 24, but all of your examples make sense when assuming that it works in the same way as that in Common Lisp (as indicated by cobbal). The Common Lisp HyperSpec says:
Syntax:
eval form
Description:
Evaluates form in the current dynamic environment and the null lexical environment.
Let's look at your examples one by one with the description in mind.
(setq lexical-binding t)
(let ((myvarr 42)) (eval 'myvarr t)) ; Lisp error: (void-variable myvarr)
Lexical binding is enabled by setting t to lexical-binding, so myvarr turns to be a lexically bound variable, which is not available inside the eval function as stated above. The eval function's option, t, is irrelevant here.
(setq lexical-binding nil)
(let ((myvarr 42)) (eval 'myvarr)) ; 42
Lexical binding is disabled by setting nil to lexical-binding, so myvarr turns to be a dynamically bound variable, which is available inside the eval function. The eval function's option, implicilty nil, is irrelevant here.
(setq lexical-binding t)
(let ((myvarr 42)) (eval 'myvarr)) ; Lisp error: (void-variable myvarr)
Lexical binding is enabled by setting t to lexical-binding, so myvarr turns to be a lexically bound variable, which is not available inside the eval function. The eval function's option, implicilty nil, is irrelevant here.
(ignore-errors (let ((myvarr 42)) (eval 'myvarr))) ; nil
Ditto.
(setq lexical-binding nil)
(eval (let ((myvarr 42)) (eval 'myvarr)) t) ; 42
Lexical-binding is disabled by setting nil to lexical-binding, so myvar turns to be a dynamically bound variable, which is available inside the inner eval function. Note that the let form, including the inner eval function, is evaluated as argument preparation before the outer eval is called. Neither the outer nor inner eval function's option is relevenat here.
(eval '(let ((myvarr 42)) (eval 'myvarr)) t) ; Lisp error: (void-variable myvarr)
myvarr turns to be a lexically bound variable, which is not available inside the inner eval. Note that, because of ', the let form is evaluated by the outer eval function with lexical binding enabled. The outer eval function's option is relevant here while the inner eval function's is not.
Why the null lexical environment?
That is, I think, because that alpha-equivalence would not hold anymore if the current lexical environment were used.
Alpha-equivalence is a formal way to say that the names of function parameters are not important. For example, (lambda (x) x) and (lambda (y) y) are alpha-equivalent, and we have regarded them as the same. Alpha-equivalence allows us to change a function parameter's name as we wish at any time. We take it for granted, and we will be very surprised if it does not hold. See Lambda calculus and Alpha-equivalence for more formal explanation.
But alpha-equivalence turns out to have some problem when a code value involving a free variable (called open code) can be passed around as in Lisp. Let's see the following example:
;;; -*- lexical-binding: t -*-
(lambda (x) (lambda (y) (eval x))) '(1+ y)
If eval evaluated under the current lexical environment, the form would be equivalent to (lambda (y) (1+ y)). Now see the following program:
(lambda (x) (lambda (z) (eval x))) '(1+ y)
This program is different from the previous one only in its parameter's name, z in place of y, so we naturally expect them to behave in the same way. But the latter program evaluates to (lambda (z) (1+ y)), which is definitely different from (lambda (y) (1+ y). Think about what will happen when the resulting function values are applied to the same argument. The point is that the name of a function parameter DOES matter when a code value containing a free variable is allowed.
Here we have two choices in order to preserve alpha-equivalence: we cannot give up alpha-equivalence because it feels so natural and we have been so much accustomed to it. The first option is to have eval evaluated under the null lexical environment as (Common) Lisp does. With this option, the free variable y in (1+ y) does not bind to the formal parameter y in (lambda (y) ...). So those two program behave consistently and alpha-equivalence is preserved well. The other choice is to preclude the problem by not allowing open code value from the beginning. I have heard that it is a method chosen by MetaOCaml
Someone may ask "if so, why the current dynamic environment?". For dynamically bound (a.k.a. special) variables, we already acknowledge well that their names are so important and that, if you change them carelessly, your program will be broken.
The odd behavior of your inner eval forms seems similar to that of symbol-value or add-to-list under lexical binding.
emacs lexical scoping and quoted variables
Under lexical binding, a symbol's value cell only holds global values, (which can be different from the variables' lexical binding value).
Use of quoted variables (such as in (eval 'var), (eval '(print var)), (add-to-list 'var 1)) only get or set on the symbol's value cell.
Practices to avoid encountering this kind of gotcha are:
Try to define and use macros rather than eval whenever possible
If you want to create/declare a global variable, refrain from using setq to create it, use defvar, defcustom or defconst to create it as a special variable instead. Special variables are always dynamically scoped, even in lexical binding mode.
Related
I'm trying to write a macro that takes a list of variables and a body of code and makes sure variables revert to their original values after body of code is executed (exercise 10.6 in Paul Graham's ANSI Common Lisp).
However, I'm unclear on why my gensym evaluates as I expect it to in one place, but not another similar one (note: I know there's a better solution to the exercise. I just want to figure out why the difference in evaluation).
Here's the first definition where the lst gensym evaluates to a list inside of the lambda passed to the mapcar:
(defmacro exec-reset-vars-1 (vars body)
(let ((lst (gensym)))
`(let ((,lst ,(reduce #'(lambda (acc var) `(cons ,(symbol-value var) ,acc))
vars
:initial-value nil)))
,#body
,#(mapcar #'(lambda (var) `(setf ,var (car ,lst)))
vars))))
But while it works exactly as I expect it to, it's not a correct solution to the exercise because I'm always grabbing the first element of lst when trying to reset values. I really want to map over 2 lists. So now I write:
(defmacro exec-reset-vars-2 (vars body)
(let ((lst (gensym)))
`(let ((,lst ,(reduce #'(lambda (acc var) `(cons ,(symbol-value var) ,acc))
vars
:initial-value nil)))
,#body
,#(mapcar #'(lambda (var val) `(setf ,var ,val))
vars
lst))))
But now I get an error that says #:G3984 is not a list. If I replace it with (symbol-value lst) I get an error saying variable has no value. But why not? Why does it have a value inside of the setf in lambda, but not as an argument passed to mapcar?
At macroexpansion time you try to map over the value of lst, which is a symbol at that time. So that makes no sense.
Trying to get symbol value also makes no sense, since lst's bindings are lexical and symbol-value is not a way to access that. Other bindings are not available at that time.
Clearly lst has a value at macroexpansion time: a symbol. This is what you see inside the lambda.
You need to make clear what values are computed at macroexpansion time and which at runtime.
An advice about naming:
lst is a poor name in Lisp, use list
the name lst makes no sense, since its value is not a list, but a symbol. I'd call it list-variable-symbol. Looks long, doesn't it? But it is much clearer. You would now that it is a symbol, used as the name for a variable holding lists.
I'm pretty sure you are overthinking it. Imagine this:
(defparameter *global* 5)
(let ((local 10))
(with-reset-vars (local *global*)
(setf *global* 20)
(setf local 30)
...))
I imagine the expansion is as easy as:
(defparameter *global* 5)
(let ((local 10))
(let ((*global* *global*) (local local))
(setf *global* 20)
(setf local 30)
...)
(print local)) ; prints 10
(print *global*) ; prints 5
let does the reset on it's own so you see that the macro should be very simple just making shadow bindings with let, unless I have misunderstood the assignment.
Your overly complicated macros does pretty bad things. Like getting values of global symbols compile time, which would reset them to the time the function that used this instead of before the body.
I'm doing a small project just for fun, and I added eval support for it to make debug easier. But later I found a problem:
(let ((x 1))
(eval (1+ x)))
(defun foo (x form)
(eval form))
(foo 1 '(1+ x))
Code above won't work. Could someone please explain why and how to work it around? Thanks very much.
First, though
(let ((x 1))
(eval (1+ x)))
may look like it does work (it certainly does something), it is likely not doing, what you intend it to do. eval is a regular function, so it receives its arguments evaluated by the caller. Effectively, you are calling eval with an integer value of 2 -- which is then "evaluated" (since integers are self-quoting) to a result value of 2.
In
(defun foo (x form)
(eval form))
it's easier to diagnose the failure. Run-time lexical bindings are not first-class objects, but something maintained by the interpreter/compiler behind the scenes. Regular functions (like eval) cannot access lexical variables defined at their call-sites.
One work-around would be to use special variables:
(defun foo (x form)
(declare (special x))
(eval form))
The declaration tells your lisp implementation, that x should be dynamically bound within its scope.
I am trying to make a macro that creates a function that takes S-expresions and evaluates them inside the lexical context of the fixture. Here is the macro I wrote:
(defmacro def-fixture (name bindings)
"Return a function that takes the form to execute but is wrapped between a let of the bindings"
`(defun ,(intern (symbol-name name)) (body)
(let (,bindings)
(unwind-protect
(progn
body)))))
But when I run it it appears to be executing outside the lexical context I provided
(def-fixture test-fixture '(zxvf 1))
(test-fixture '(= zxvf 1))
let: Symbol's value as variable is void: zxvf
Btw, I have enabled the variable lexical binding. Any ideas as to what is my mistake?
This has nothing to do with lexical scoping. Your macro call expands to:
(defun test-fixture (body)
(let ((quote (zxvf 1)))
(unwind-protect (progn body))))
Which is of course not what you intended. I do not believe that (test-fixture '(= zxvf 1)) signals the error you cite (i.e. variable is void). Instead, the call signals (void-function zxvf) because it tries to evaluate (zxvf 1). The (= zxvf 1) expression is never evaluated, since it's quoted.
You might like to try something more like:
(defmacro def-fixture (name bindings)
"Return a macro that takes the form to execute but is wrapped between a let of the bindings"
`(defmacro ,name (body)
`(let (,',bindings)
(unwind-protect
(progn
,body)))))
and then use it as in:
(def-fixture test-fixture (zxvf 1))
(test-fixture (= zxvf 1))
The following note is in the emacs manual:
Also, the code in the body of a defun or defmacro cannot refer to
surrounding lexical variables.
It might be what your problem is.
Also I do not know if you need to quote the second argument of def-fixture. I used the macrostep package to inspect the resulting macro and the result seems better without the quote.
To be brief. Here is my several tries to intern and use a symbol in clisp.
[1]> (setq sym (intern "foo"))
|foo|
[2]> (eq sym 'foo)
NIL
Why???
[3]> (defun internup (me &optional (package *package*))
(intern (string-upcase me) package))
INTERNUP
[4]> (eq 'abc (internup "abc"))
T
Probably must be upcase.
[12]>(let ((abc 2))
(eval '(+ 2 abc)))
*** - EVAL: variable ABC has no value
The following restarts are available:
ok
[18]> (let ((abc 2))
(eval '(+ 2 'abc)))
*** - +: ABC is not a number
The following restarts are available:
Interesting. Should I set it before.
[14]> (setq a (internup "abc"))
ABC
[15]> (let ((abc 2))
(eval '(+ 2 a)))
*** - +: ABC is not a number
The following restarts are available:
And again wrong. Hmm I must be missing some important fact about interning symbols in LISP. Can you help me ?
Your problem has nothing to do with interning.
The first problem is indeed causes by the fact that the reader will always uppercase the symbols, so you need to call (intern "FOO") in order to get the same result as 'foo.
The problem with EVAL is caused by the fact that LET introduces a lexical binding which is not visible inside EVAL. If you really want this to work you'd have to declare abc to be special, like so:
(let ((abc 2))
(declare (special abc))
(eval '(1+ abc)))
A special declaration will cause the variable to have dynamic binding, instead of lexical binding (the latter means that the binding is limited to the local lexical context, i.e. within the LET form. With the special declaration the variable is available to anything that is called by from that form).
Note that the use of both special declarations and eval is something you should be very careful about and you should probably rethink your use of EVAL in the first place. It is very rare that you actually need to use it. In most cases you're actually looking for the use of lambda functions instead.
Eval evaluates the form in the null lexical environment, i.e. with no lexical bindings. That has nothing to do with the interning of symbols.
The case-sensitivity of the Common Lisp reader is determined by the readtable:
(readtable-case *readtable*)
Typically the reader will initially intern symbols in uppercase (unless you explicitly escape characters). Hence:
(eq (intern "foo") 'foo) => NIL
(eq (intern "FOO") 'foo) => T
(eq (intern "FOo") 'fo\o) => T
You can use backquote syntax to build the form for eval:
(let ((abc 2))
(eval `(+ 2 ,abc)))
=> 4
I have an s-expression bound to a variable in Common Lisp:
(defvar x '(+ a 2))
Now I want to create a function that when called, evaluates the expression in the scope in which it was defined. I've tried this:
(let ((a 4))
(lambda () (eval x)))
and
(let ((a 4))
(eval `(lambda () ,x)))
But both of these create a problem: EVAL will evaluate the code at the top level, so I can't capture variables contained in the expression. Note that I cannot put the LET form in the EVAL. Is there any solution?
EDIT: So if there is not solution to the EVAL problem, how else can it be done?
EDIT: There was a question about what exactly I am try to do. I am writing a compiler. I want to accept an s-expression with variables closed in the lexical environment where the expression is defined. It may indeed be better to write it as a macro.
You need to create code that has the necessary bindings. Wrap a LET around your code and bind every variable you want to make available in your code:
(defvar *x* '(+ a 2))
(let ((a 4))
(eval `(let ((a ,a))
,*x*)))
CLISP implements an extension to evaluate a form in the lexical environment. From the fact that it is an extension, I suspect you can't do that in a standard-compliant way.
(ext:eval-env x (ext:the-environment))
See http://clisp.cons.org/impnotes.html#eval-environ.
What is the actual problem that you want to solve? Most likely, you're trying to tackle it the wrong way. Lexical bindings are for things that appear lexically within their scope, not for random stuff you get from outside.
Maybe you want a dynamic closure? Such a thing doesn't exist in Common Lisp, although it does in some Lisp dialects (like Pico Lisp, as far as I understand).
Note that you can do the following, which is similar:
(defvar *a*)
(defvar *x* '(+ *a* 2)) ;'
(let ((a 10))
;; ...
(let ((*a* a))
(eval *x*)))
I advise you to think hard about whether you really want this, though.
In Common Lisp you can define *evalhook* Which allows you to pass an environment to (eval ...). *evalhook* is platform independent.
It is possible to use COMPILE to compile the expression into function and then use PROGV to FUNCALL the compiled function in the environment where variables are dynamically set. Or, better, use COMPILE to compile the expression into function that accepts variables.
Compile accepts the function definition as a list and turns it into function. In case of SBCL, this function is compiled into machine code and will execute efficiently.
First option (using compile and progv):
(defvar *fn* (compile nil '(lambda () (+ a 2)))
(progv '(a) '(4) (funcall *fn*))
=>
6
Second option:
(defvar *fn* (compile nil '(lambda (a) (+ a 2))))
(funcall *fn* 4)
=>
6