在 emacs lisp 中定义一个 let 宏作用域
Defining a let macro scope in emacs lisp
在 emacs lisp 中(但也欢迎与普通 lisp 相关的答案)我有一个使用宏的库,我想仅在特定上下文中执行时劫持宏的参数之一。本质上我想要的是一个宏:
; My macro. This is a sketch of what I want that doesn't work.
(defmacro hijack-f (body)
`(macrolet ((f (x) `(f (+ 1 ,x))))
,@body))
; Defined in the library, I don't want to deal with these
(defmacro f (x) x)
(defun g (x) (f x))
所以
(g 1) ; => 1
(hijack-f (g 1)) ; => 2
(hijack-f (hijack-f (g 1))) ; => 3
编辑:@melpomene 和@reiner-joswig 正确地指出 f
在 hijack-f
之前在 g
中扩展。作为后续行动是否有 hijack-f
这样的:
(f 1) ; => 1
(hijack-f (f 1)) ; => 2
(hijack-f (hijack-f (f 1))) ; => 3
据我所知,你想要的是不可能的,因为 g
不包含对 f
的调用。相反 f
运行 first 并扩展到 g
.
的(部分)定义
即:
(defun g (x) (f x))
马上变成
(defun g (x) x)
然后将 g
定义为函数(其值为 (lambda (x) x)
)。
在运行时与 f
打交道不会影响任何事情,因为在您调用 g
.
时它的调用早已消失
如果您很高兴 f
是一个函数而不是一个宏,并且使用 CL 而不是 elisp,那么您正在寻找 flet
和这样一个宏:
(defmacro hijack-f (&body body)
`(flet ((f (x)
(f (1+ x))))
,@body))
给定 f
的全局定义:
(defun f (x)
x)
然后
> (hijack-f (f 1))
2
> (hijack-f (hijack-f (f 1)))
3
以此类推
(正如其他人所指出的,您不能劫持已经用这样的宏编译的代码:您需要让 f
配合劫持才能做到这一点。)
在 emacs lisp 中(但也欢迎与普通 lisp 相关的答案)我有一个使用宏的库,我想仅在特定上下文中执行时劫持宏的参数之一。本质上我想要的是一个宏:
; My macro. This is a sketch of what I want that doesn't work.
(defmacro hijack-f (body)
`(macrolet ((f (x) `(f (+ 1 ,x))))
,@body))
; Defined in the library, I don't want to deal with these
(defmacro f (x) x)
(defun g (x) (f x))
所以
(g 1) ; => 1
(hijack-f (g 1)) ; => 2
(hijack-f (hijack-f (g 1))) ; => 3
编辑:@melpomene 和@reiner-joswig 正确地指出 f
在 hijack-f
之前在 g
中扩展。作为后续行动是否有 hijack-f
这样的:
(f 1) ; => 1
(hijack-f (f 1)) ; => 2
(hijack-f (hijack-f (f 1))) ; => 3
据我所知,你想要的是不可能的,因为 g
不包含对 f
的调用。相反 f
运行 first 并扩展到 g
.
即:
(defun g (x) (f x))
马上变成
(defun g (x) x)
然后将 g
定义为函数(其值为 (lambda (x) x)
)。
在运行时与 f
打交道不会影响任何事情,因为在您调用 g
.
如果您很高兴 f
是一个函数而不是一个宏,并且使用 CL 而不是 elisp,那么您正在寻找 flet
和这样一个宏:
(defmacro hijack-f (&body body)
`(flet ((f (x)
(f (1+ x))))
,@body))
给定 f
的全局定义:
(defun f (x)
x)
然后
> (hijack-f (f 1))
2
> (hijack-f (hijack-f (f 1)))
3
以此类推
(正如其他人所指出的,您不能劫持已经用这样的宏编译的代码:您需要让 f
配合劫持才能做到这一点。)