gpt4 book ai didi

macros - Lisp 评估宏表达式中的变量

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

我有以下功能(我是 Lisp 的初学者):

(defun my-fun (a b)
(my-commandsend-and-reply-macro (cmd)
(:reply (ok result)
(do-something a b result)))
)

其中 my-commandsend-and-reply-macro 是另一个程序员编写的宏。我无法修改它。

my-commandsend-and-reply-macro 发送一个命令(在这个例子中是 cmd)到一个服务器进程(它是用另一种编程语言编写的)然后等待它的回答。然后使用用户给定的“:代码的回复部分”在宏中处理答案。列表(ok 结果)是一种模式,在宏中,解构绑定(bind)解构并将答案的适当部分绑定(bind)到 ok 和结果(ok 只是一个标志)。在此之后,执行“:reply 部分”的其他用户给定行。 (用于结果处理)

我想做以下事情:

1、向其他进程发送命令(这样就可以了)

2,使用结果调用函数(比如做某事)并使用一些其他参数,这些参数是 my-fun 的实际参数(这部分失败...)

我该怎么做?我认为问题是 a 和 b 在宏扩展之前没有被评估,当宏扩展时 Lisp 搜索本地 a 和 b 但没有 a 或 b。有没有办法评估a和b? (因此宏可以将它们视为具体值)

这是宏定义:(由另一个程序员编写)

(defmacro* my-commandsend-and-reply-macro ((cmd &rest args) &body body)
`(progn
(with-request-id ()
(setf (gethash *request-id* *my-callbacks*)
(lambda (status &rest status-args)
(case status
,@(loop for (kind . clause) in body when (eql kind :reply)
collect
(destructuring-bind
((status-flag &rest lambda-form-pattern)
&body action-given-by-user) clause
`(,status-flag
(destructuring-bind ,lambda-form-pattern status-args
,@action-given-by-user))))
((error)
(message "Error: %s" (elt (elt status-args 0) 1))))))
(apply #'send-command-to-process *request-id* cmd args)))))

with-request-id 定义:

(defmacro* with-request-id ((&rest vars) &body body)
"Send `getid' to the server, and call `body' once the response
with the new ID has arrived. By then, global variable `*request-id*'
is bound to the latest request ID."
`(progn
(when (not (server-is-running))
(error "Server isn't running!"))
(when *reqid-queue*
(error "Some internal error occured. Please, restart the program!"))
(lexical-let (,@(loop for var in vars
collect `(,var ,var)))
(setf *reqid-queue* (lambda ()
(unwind-protect
(progn ,@body)
(setf *reqid-queue* nil)))))
(get-id)))

并从其他进程获取 id:

(defun get-id ()
(send-command-to-process 'getid))

最佳答案

根本没有查看您的代码(抱歉——没时间)---

ab 由函数 my-fun 求值。 所有 函数评估它们的参数以开始 — 只有宏和特殊形式不一定评估它们的所有参数。

但是那些 ab没有传递给宏——唯一传递给它的是未计算的 sexp 绑定(bind)到 cmd。而且您甚至没有在函数中定义 cmd!

您需要做的是将ab 替换到cmd sexp 中。您根本没有显示 cmd 是如何定义/构造的。使用 ab 的值构造它,你应该没问题。

要构造 cmd sexp,请记住您可以使用反引号语法来简化事情,使用逗号语法传递 ab。例如

 (let ((cmd  `(some funny (expression) that ((uses)) ,a AND ,b)))
code-that-uses-CMD)

这假定您传递给宏的代码不需要变量 ab,它只需要它们的值(value)观

关于macros - Lisp 评估宏表达式中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19599554/

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