gpt4 book ai didi

lambda - 使匿名函数易于区分

转载 作者:行者123 更新时间:2023-12-01 15:17:42 25 4
gpt4 key购买 nike

我想为一类匿名函数添加一些元数据,以便于识别它们。到目前为止,我所有的想法都是骇人听闻的或值得怀疑的:

plist 项可以工作,但显然它只适用于符号,不适用于 lambda。

我可以在文档字符串中插入一些内容:

(lambda (x) "is-special" ...

但这看起来真的很难看,或者:

(lambda (x)
(if
(eq x 'special)
t
...

甚至更丑。

是否有一种不太糟糕的方式来设置函数对象的属性?

我还可以使用类型系统来区分我的函数:

将函数放在结构体或 CLOS 对象中是可能的,但感觉很麻烦。

是否可以创建作为函数类型的自定义子类型的 lambda?

能否使 CLOS 对象充当可执行函数?我在想类似于 python 的 call 属性的东西。

最佳答案

我对 MOP 的了解还不够多,无法回答你最后的问题,但我可以建议你用一种骇人听闻的方式来做你想做的事。

您可以声明一个特殊变量来跟踪已添加元数据的 lambda:(defvar *annotated-lambdas* (make-hash-table))

然后定义一个函数来从中获取/设置 lambda。

(defun get-lambda (lambda &optional (annotated-lambdas *annotated-lambdas*))
(gethash lambda annotated-lambdas))

(defun (setf get-lambda) (annotation lambda &optional (annotated-lambdas *annotated-lambdas*))
(setf (gethash lambda annotated-lambdas) annotation))

现在你已经可以测试一些东西了:

(let ((l (lambda (x) (1+ x))))
(setf (get-lambda l) "Add one."))

此时 *annotated-lambdas* 中应该已经有一个元素了。

现在您可以使用一个小宏来简化此操作:

(defmacro lambda* ((&rest args) (annotation &optional (annotated-lambdas *annotated-lambdas*)) &body body)
(let ((name (gensym)))
`(let ((,name (lambda (,@args)
,@body)))
(setf (get-lambda ,name ,annotated-lambdas) ,annotation))))

你可以这样使用:

(lambda* (x) ("Add one.")
(+1 x))

当然,要访问注释,您需要访问 lambda,我假设您这样做,否则您将使用一个函数(它只是一个指向 lambda 的符号)。此外,“注释”可以是任何内容,字符串、列表、列表、plist 甚至哈希表。

关于lambda - 使匿名函数易于区分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27558980/

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