(Please see what is letrec
first.)
The following code is obviously fine and self-explanatory:
;; -*- lexical-binding: t; -*-
(setq post-self-insert-hook `(,@(when (boundp 'post-self-insert-hook)
post-self-insert-hook)
,(letrec ((_ (lambda ()
(message ":P")
(remove-hook 'post-self-insert-hook _))))
_)))
But if I use custom-set-variables
,
;; -*- lexical-binding: t; -*-
(custom-set-variables
'(post-self-insert-hook `(,@(when (boundp 'post-self-insert-hook)
post-self-insert-hook)
;; Manual says `letrec' is
;; only useful when lexical
;; binding is in effect.
;; But `custom-set-variables'
;; evaluates these forms by
;; calling `eval', which uses
;; dynamic scope by default.
,(let ((lexical-binding t))
(letrec ...)))))
Emacs will complain that Symbol’s value as variable is void: _
.
Why the above code snippet doesn't work?
Irrelevant to This Question
For those who are not quite familiar with backquote:
(custom-set-variables
'(post-self-insert-hook `(,@(when (boundp 'post-self-insert-hook)
post-self-insert-hook)
,(let ((_ (lambda () "123")))
_))))
;; => nil
post-self-insert-hook
;; => (... (lambda nil "123"))
As you can see, the forms that are expected to be evaluated are indeed evaluated.