首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在emacs lisp中定义let宏作用域

在emacs lisp中定义let宏作用域
EN

Stack Overflow用户
提问于 2018-05-05 15:27:24
回答 2查看 493关注 0票数 2

在emacs中(但与普通lisp相关的答案也是受欢迎的),我有一个使用宏的库,只有在特定的上下文中执行时,我才想劫持宏的一个参数。基本上,我想要的是一个宏:

代码语言:javascript
运行
复制
; 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))

所以

代码语言:javascript
运行
复制
(g 1) ; => 1
(hijack-f (g 1)) ; => 2
(hijack-f (hijack-f (g 1))) ; => 3

编辑:@melpomene和@reiner-joswig正确地指出,f是在hijack-f之前在g中扩展的。作为后续行动,是否存在这样一个hijack-f

代码语言:javascript
运行
复制
(f 1) ; => 1
(hijack-f (f 1)) ; => 2
(hijack-f (hijack-f (f 1))) ; => 3
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-05 15:38:36

据我所知,您想要的是不可能的,因为g不包含对f的调用。相反,f首先运行并扩展到( g的一部分)定义。

这就是:

代码语言:javascript
运行
复制
(defun g (x) (f x))

立即变成

代码语言:javascript
运行
复制
(defun g (x) x)

然后将g定义为一个函数(其值为(lambda (x) x))。

在运行时处理f不会影响任何事情,因为在调用g时,它的调用早就消失了。

票数 2
EN

Stack Overflow用户

发布于 2018-05-05 17:42:55

如果您高兴地看到您的f是一个函数而不是一个宏,并且使用CL not elisp,那么您需要的是flet和这样的宏:

代码语言:javascript
运行
复制
(defmacro hijack-f (&body body)
  `(flet ((f (x)
            (f (1+ x))))
     ,@body))

给出了f的全局定义

代码语言:javascript
运行
复制
(defun f (x)
  x)

然后

代码语言:javascript
运行
复制
> (hijack-f (f 1))
2

> (hijack-f (hijack-f (f 1)))
3

诸若此类。

(正如其他人所指出的,您不能劫持已经用像这样的宏编译过的代码:您需要让f合作进行劫持。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50191083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档