gpt4 book ai didi

macros - 没有评估的取消引用

转载 作者:太空宇宙 更新时间:2023-11-03 18:46:50 25 4
gpt4 key购买 nike

我以引用的形式存储一些宏(因为实际上它们会产生具有复杂词法环境的 lambda,我更喜欢将它们存储并序列化为列表)。所以现在我正在尝试:

(defun play (s)
(funcall (macroexpand s)))

Macroexpand 计算引用的 lambda,因此 funcall 无法运行它。如何在没有 eval 的情况下取消引用 macroexpand 的结果?因为在我的情况下,这会导致无法防御的安全漏洞。

更多信息:

我得到的是这样的(在最简单的情况下):

FUNCALL: #1=#'(LAMBDA (#:G6008) (SYMBOL-MACROLET NIL T)) is not a function name; try using a symbol instead

symbol-macrolet 是在内部 lambda 中实际构建“棘手的词法环境”的东西。

最佳答案

Macroexpand evaluates quoted lambda, so funcall can't run it. How to unquote result of macroexpand without eval? Because in my case it would cause indefensible security hole.

我认为 Sylwester 关于 XY problem 的评论大概就在这里;听起来您正在尝试做一些可能以不同方式做得更好的事情。也就是说,如果您有一个 lambda 表达式列表,您可以使用 coerce 来获取函数对象,而不是使用 eval。也就是说,您可以这样做:

CL-USER> (funcall '(lambda () 42))
; Error, like you've been having

CL-USER> (funcall (coerce '(lambda () 42) 'function))
42 ; turned the list (lambda () 42) into a function and called it

coerce 的文档中对此进行了描述;当“输出”类型为 function 时,对象参数会发生以下情况:

If the result-type is function, and object is any function name that is fbound but that is globally defined neither as a macro name nor as a special operator, then the result is the functional value of object.

If the result-type is function, and object is a lambda expression, then the result is a closure of object in the null lexical environment.

因此,如果您有一个函数返回 (lambda ...) 形式的列表,您可以使用 coercefuncall及其结果。这包括宏展开,虽然你可能想使用 macroexpand-1 而不是 macroexpand,因为 lambda 已经是一个宏,所以如果你展开太多至此,(lambda () ...) 变成了 (function (lambda () ...))

CL-USER> (defmacro my-constantly (value)
`(lambda () ,value))
MY-CONSTANTLY
CL-USER> (macroexpand-1 '(my-constantly 36))
(LAMBDA () 36)
T
CL-USER> (funcall (coerce (macroexpand-1 '(my-constantly 36)) 'function))
36

但是,如果您尝试使用普通的 macroexpand,就会出现问题。认为自己受到警告:

CL-USER> (macroexpand '(my-constantly 36))
#'(LAMBDA () 36) ; not a list, but a function
T
CL-USER> (funcall (coerce (macroexpand '(my-constantly 36)) 'function))
; Error. :(

关于macros - 没有评估的取消引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23980871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com