Elisp 在 progn 上使用 apply 函数列表
Elisp use apply on progn for list of functions
我是一个新的 emacs 用户。并尝试编写一些 Elisp 来更好地学习这个软件。虽然我遇到了一些问题。
我想在 progn
到 运行 上按顺序使用 apply
函数列表。但我得到如下错误。我只是很困惑,需要一些帮助来告诉我如何在 Elisp 中实现这一点,谢谢。
(progn
(+ 1 1)
(+ 2 2)
)
;; => 4
(apply #'progn ((+ 1 1) (+ 2 2)))
;; => Invalid function: (+ 1 1)
(apply #'progn ('(+ 1 1) '(+ 2 2)))
;; => Invalid function: '(+ 1 1)
(apply #'progn '((+ 1 1) (+ 2 2)))
;; => Invalid function: #<subr progn>
我玩上面的玩具因为我从 vim 来到 emacs。所以我安装了evil和evil number。并想要返回 vim 数字 inc 和 dec 绑定 C-a,C-x。所以我写了一个宏来避免样板文件。
(defmacro set-evil-number-keymap (key-set func &rest modes)
`(apply 'progn
,(-map
(lambda (mode)
`(define-key ,(intern (concat "evil-" mode "-state-map")) (kbd ,key-set)
',(intern
(concat "evil-numbers/" func))))
,modes)))
(set-evil-number-keymap "C-a" "inc-at-pt" "normal" "insert")
(set-evil-number-keymap "C-x" "dec-at-pt" "normal" "insert")
我的期望值低于此。虽然它不是 运行.
(progn
(define-key evil-normal-state-map (kbd "C-a") ’evil-numbers/inc-at-pt) (define-key evil-visual-state-map (kbd "C-a") ’evil-numbers/inc-at-pt))
(progn
(define-key evil-normal-state-map (kbd "C-x") ’evil-numbers/dec-at-pt) (define-key evil-visual-state-map (kbd "C-x") ’evil-numbers/dec-at-pt))
您不能像 progn
那样在 "special forms" 上调用 apply
(请参阅信息 (elisp)特殊形式),它们具有独特的评估规则。
progn
本身已经提供了一种顺序评估机制,因此您的初始尝试确实可以满足您的要求。然而,在顶层,表单无论如何都会按顺序执行,所以那里不需要 progn
。
不确定您在期待什么。 progn
returns最后几格的值,所以4除外,参考C-h f progn
:
progn is a special form in `C source code'.
(progn BODY...)
Eval BODY forms sequentially and return value of last one.
如果你想看到(+ 1 1)
的结果,你需要请求它,例如
(list (+ 1 1) (+ 2 2))
;; => (2 4)
;; Step 1
(list 2 (+ 2 2))
;; Step 2
(list 2 4)
;; Step 3
(2 4)
函数参数是从左到右求值的。顺便说一下,Emacs Lisp 不支持多个 return 值。
(apply #'progn ((+ 1 1) (+ 2 2)))
;; => Invalid function: (+ 1 1)
由于函数apply
的第二个参数是((+ 1 1) (+ 2 2))
,Emacs需要计算它的值,计算形式如(foo 1 2 3)
,foo
必须是函数,但 (+ 1 2)
不是函数,它只是一个包含 3 个元素的普通列表。
(apply #'progn ('(+ 1 1) '(+ 2 2)))
;; => Invalid function: '(+ 1 1)
'(+ 1 2)
,即(quote (+ 1 2))
也不是一个函数,它是一个有两个元素的列表。
(apply #'progn '((+ 1 1) (+ 2 2)))
;; => Invalid function: #<subr progn>
progn
不是函数,它是一种特殊形式。 and
、or
、let
和 while
都是特殊形式,它们就像宏一样,不会急切地计算参数。
(elisp) Calling Functions 提及
special forms and macros do not make sense in `apply'.
您不需要在宏中使用 apply
,elisp 有 ,@
可以将列表展平为参数。所以正确答案是
(defmacro set-evil-number-keymap (key-set func &rest modes)
`(progn
,@(-map
(lambda (mode)
`(define-key ,(intern (concat "evil-" mode "-state-map")) (kbd ,key-set)
',(intern
(concat "evil-numbers/" func))))
,modes)))
你有一点 XY 问题,但对你的名义问题有用的是
(eval (cons 'progn
'((print (+ 1 1))
(print (+ 2 2)))))
eval
是 generally considered a beginner programmer's misunderstanding, but in this case you just can't use apply
for the reasons Rorschach explained. Elisp actually follows the Common Lisp spec here, which says 对于 apply
那
it is illegal for the symbol to be the name of a macro or special form
所以,一般来说,您必须直接在您通过 cons
将 progn
编译到您的“指令列表”的程序上使用 eval
。
我是一个新的 emacs 用户。并尝试编写一些 Elisp 来更好地学习这个软件。虽然我遇到了一些问题。
我想在 progn
到 运行 上按顺序使用 apply
函数列表。但我得到如下错误。我只是很困惑,需要一些帮助来告诉我如何在 Elisp 中实现这一点,谢谢。
(progn
(+ 1 1)
(+ 2 2)
)
;; => 4
(apply #'progn ((+ 1 1) (+ 2 2)))
;; => Invalid function: (+ 1 1)
(apply #'progn ('(+ 1 1) '(+ 2 2)))
;; => Invalid function: '(+ 1 1)
(apply #'progn '((+ 1 1) (+ 2 2)))
;; => Invalid function: #<subr progn>
我玩上面的玩具因为我从 vim 来到 emacs。所以我安装了evil和evil number。并想要返回 vim 数字 inc 和 dec 绑定 C-a,C-x。所以我写了一个宏来避免样板文件。
(defmacro set-evil-number-keymap (key-set func &rest modes)
`(apply 'progn
,(-map
(lambda (mode)
`(define-key ,(intern (concat "evil-" mode "-state-map")) (kbd ,key-set)
',(intern
(concat "evil-numbers/" func))))
,modes)))
(set-evil-number-keymap "C-a" "inc-at-pt" "normal" "insert")
(set-evil-number-keymap "C-x" "dec-at-pt" "normal" "insert")
我的期望值低于此。虽然它不是 运行.
(progn
(define-key evil-normal-state-map (kbd "C-a") ’evil-numbers/inc-at-pt) (define-key evil-visual-state-map (kbd "C-a") ’evil-numbers/inc-at-pt))
(progn
(define-key evil-normal-state-map (kbd "C-x") ’evil-numbers/dec-at-pt) (define-key evil-visual-state-map (kbd "C-x") ’evil-numbers/dec-at-pt))
您不能像 progn
那样在 "special forms" 上调用 apply
(请参阅信息 (elisp)特殊形式),它们具有独特的评估规则。
progn
本身已经提供了一种顺序评估机制,因此您的初始尝试确实可以满足您的要求。然而,在顶层,表单无论如何都会按顺序执行,所以那里不需要 progn
。
不确定您在期待什么。 progn
returns最后几格的值,所以4除外,参考C-h f progn
:
progn is a special form in `C source code'.
(progn BODY...)
Eval BODY forms sequentially and return value of last one.
如果你想看到(+ 1 1)
的结果,你需要请求它,例如
(list (+ 1 1) (+ 2 2))
;; => (2 4)
;; Step 1
(list 2 (+ 2 2))
;; Step 2
(list 2 4)
;; Step 3
(2 4)
函数参数是从左到右求值的。顺便说一下,Emacs Lisp 不支持多个 return 值。
(apply #'progn ((+ 1 1) (+ 2 2)))
;; => Invalid function: (+ 1 1)
由于函数apply
的第二个参数是((+ 1 1) (+ 2 2))
,Emacs需要计算它的值,计算形式如(foo 1 2 3)
,foo
必须是函数,但 (+ 1 2)
不是函数,它只是一个包含 3 个元素的普通列表。
(apply #'progn ('(+ 1 1) '(+ 2 2)))
;; => Invalid function: '(+ 1 1)
'(+ 1 2)
,即(quote (+ 1 2))
也不是一个函数,它是一个有两个元素的列表。
(apply #'progn '((+ 1 1) (+ 2 2)))
;; => Invalid function: #<subr progn>
progn
不是函数,它是一种特殊形式。 and
、or
、let
和 while
都是特殊形式,它们就像宏一样,不会急切地计算参数。
(elisp) Calling Functions 提及
special forms and macros do not make sense in `apply'.
您不需要在宏中使用 apply
,elisp 有 ,@
可以将列表展平为参数。所以正确答案是
(defmacro set-evil-number-keymap (key-set func &rest modes)
`(progn
,@(-map
(lambda (mode)
`(define-key ,(intern (concat "evil-" mode "-state-map")) (kbd ,key-set)
',(intern
(concat "evil-numbers/" func))))
,modes)))
你有一点 XY 问题,但对你的名义问题有用的是
(eval (cons 'progn
'((print (+ 1 1))
(print (+ 2 2)))))
eval
是 generally considered a beginner programmer's misunderstanding, but in this case you just can't use apply
for the reasons Rorschach explained. Elisp actually follows the Common Lisp spec here, which says 对于 apply
那
it is illegal for the symbol to be the name of a macro or special form
所以,一般来说,您必须直接在您通过 cons
将 progn
编译到您的“指令列表”的程序上使用 eval
。