eval一个symbol为什么会是void variable?

(let (a) (eval a))
=> nil
(let (a) (funcall #'eval 'a))
=> (void-variable a)

这是为什么呢?

版本??

在我这里 --26.2 正常

因为 eval 只会用 current dynamic binding 和 null lexical binding。

你可以试试先 (defvar a)

可能是我做了什么把emacs环境污染了?重启emacs就没有报错了。但是污染环境也不应该出这种问题啊……

null是指什么?

就是沒有,clean。

你开了 lexical-binding

1 个赞

确实,开了lexical-binding就会报错了,而且用(eval 'a t)eval搜索lexical scope也不行,这是为什么?你说eval只会用null lexical binding,但是我没理解什么是null lexical binding。空lexical-binding吗?那有什么意义?

第三个参数为t时,lexical env内为空,但是可以用alist制造lexical env

(eval 'a '((a . 3))) ; => 3
2 个赞

因为 emacs lisp lexical binding 的实现限制 eval 是没法自动获取当前 lexical binding 的,需要用户用 alist 的方式构建一个传进去。

有 lexical binding 后,

(let (a b)
  (list a b (eval '(list a b))))

在编译器/eval 看來会先 rename / alpha conversion 就会是类似

(let (#1=#:a212 #2=#:b312)
  (list #1# #2# (eval '(list a b))))

自然无从得知 #:b312b 有什么关系。