gpt4 book ai didi

lisp - 在 common-lisp 中,我如何覆盖/更改特定类型对象的评估行为?

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

在 common-lisp 中,我想实现一种像这样的引用系统:

假设我有:

(defclass reference () ((host) (port) (file)))

我还有:

(defun fetch-remote-value (reference) ...) 获取并反序列化 lisp 对象。

我如何干预评估过程,以便每当评估引用对象时,获取远程值并再次重新评估以产生最终结果?

编辑:

对我想要完成的事情的更详尽的描述:

我使用 cl-store 序列化 lisp 对象并将它们发送到远程文件(或数据库或任何东西)以进行保存。成功存储后,我将主机、端口和文件保存在一个引用对象中。我想,每当对引用对象调用 eval 时,首先检索该对象,然后对检索到的值调用 eval。由于引用也可以在其他(父)对象或聚合类型中序列化,我可以通过 modyfing eval 获得免费的递归远程引用解析,因此我不必自己遍历和解析加载对象的子引用。

编辑:由于对象总是对自己求值,所以我的问题有点错误。基本上我想做的是:

我想拦截符号的评估,以便当它们的值是 REFERENCE 类型的对象时,而不是返回对象作为符号评估的结果,而是返回 (fetch-remote-value object) 的结果?

最佳答案

简而言之:您不能这样做,除非重写函数 eval 并修改您的 Lisp 编译器。评估规则是固定的 Lisp 标准。

编辑 阅读扩充问题后,我认为您无法在此处实现引用的完全透明。在这样的场景中

(defclass foo () (reference :accessor ref))
(ref some-foo)

调用 ref 的结果只是一个值;无论其类型如何,都不会考虑对其进行评估。

当然,您可以以一种透明地进行解析的方式定义访问器:

(defmacro defresolver (name class slot)
`(defmethod ,name ((inst ,class))
(fetch-remote-reference (slot-value inst ',slot))))

(defresolver foo-reference foo reference)

编辑您可以(某种程度上)使用符号宏连接到 Common Lisp 的符号解析机制:

(defmacro let-with-resolution (bindings &body body) 
`(symbol-macrolet ,(mapcar #'(lambda (form) (list (car form) `(fetch-aux ,(cadr form)))) bindings) ,@body))

(defmethod fetch-aux ((any t)) any)
(defmethod fetch-aux ((any reference)) (fetch-remote-reference any))

然而,现在事情变得相当神秘了;变量不再是变量,而是魔法符号,只是看起来像变量。例如,修改由该宏“绑定(bind)”的变量的内容是不可能的。使用这种方法,您可以做的最好的事情是为 fetch-aux 提供一个 setf 扩展,它会修改原始位置。

关于lisp - 在 common-lisp 中,我如何覆盖/更改特定类型对象的评估行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6213455/

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