在 .emacs 中开启词法绑定的作用?

给代码

让我猜一猜给我上强度是吧

(let ((fn (letrec ((x (lambda ()
                                             (message ":P")
                                             (remove-hook 'post-self-insert-hook x))))
            x)))
 
(custom-set-variables
 '(post-self-insert-hook `(,@(when (boundp 'post-self-insert-hook)
                                  post-self-insert-hook)
                              ,fn))))

很简单,custom-set-variables 不会用词法作用域,也不会保留上下文。

是的,给你上强度。(电脑不在身边,手机懒得打字)

这样:

(custom 
       ‘(xxx-hook ’(,@(…)
                                ,(let ((词法绑定 t))
                                      (letrec 。。。

你加 let 在 custom-set-variables 的参数里面是 nop ,并不会达到你以为开启词法作用域的效果。

对,我其实从一开始就是想问这个问题(我猜测是这样,但我不确定)。所以理由是什么?为什么是nop呢?

理由是 let 绑定了 lexical-binding 之前解释器已经把整个表达式的词法解析过程做完了,再怎么改变 lexical-binding 也不能改变已经用动态作用域做了解析的既成事实

就是我一开始给的思考题答案

和 TeX 的 catcode 关系是 TeX 不能改变已经 tokenized 部分的 catcode,所以想改变 catcode 要保证改变在开始 tokenize 需要 catcode 起作用的部分之前就完成。

custom-set-variables 调用 eval 来处理参数,并且不会由当前的 lexical-binding 影响,只会用动态作用域。

总之,认为 custom-set-variables 和 setq 在 lexical-binding = t 时行为一致是错误的。

2 个赞

soga. 照这么说的话, 手写代码中的

(let ((lexical-binding xxx))
  ...)

都没啥实际作用是吧.

除了在 let body 里调用编译器之类的,lexical-binding 可以影响 byte-compile 的行为。

你可以去 SE 回答这个问题吗? 然后我 accept 它. 如果你懒得回答得话, 那我去回答 (当然, 我会提供指向这里的链接).