在emacs中(但与普通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发布于 2018-05-05 15:38:36
据我所知,您想要的是不可能的,因为g不包含对f的调用。相反,f首先运行并扩展到( g的一部分)定义。
这就是:
(defun g (x) (f x))立即变成
(defun g (x) x)然后将g定义为一个函数(其值为(lambda (x) x))。
在运行时处理f不会影响任何事情,因为在调用g时,它的调用早就消失了。
发布于 2018-05-05 17:42:55
如果您高兴地看到您的f是一个函数而不是一个宏,并且使用CL not 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合作进行劫持。)
https://stackoverflow.com/questions/50191083
复制相似问题