Macros 宏表达式中的Lisp求值变量

Macros 宏表达式中的Lisp求值变量,macros,lisp,elisp,common-lisp,clisp,Macros,Lisp,Elisp,Common Lisp,Clisp,我有以下功能(我是Lisp的初学者): 其中,我的commandsend和reply宏是由另一个程序员编写的宏。我无法修改它 我的commandsend和reply宏将命令(在本例中为cmd)发送到服务器进程(用另一种编程语言编写),然后等待其应答。 然后在宏中使用用户给定的“:代码的回复部分”处理答案。列表(ok result)是一种模式,在宏中,解构绑定解构并将答案的适当部分绑定到ok和result(ok只是一个标志)。在此之后,执行“:reply part”的其他用户给定行。(用于结果处理

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

其中,我的commandsend和reply宏是由另一个程序员编写的宏。我无法修改它

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

我想做以下工作:

1,向另一个进程发送类似的命令(这是确定的)

2、使用结果调用函数(如do something)并使用其他一些参数,这些参数是我的乐趣的实际参数(此部分失败…)

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

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

请求id为的的Def:

(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))

根本不查看代码(抱歉--没时间)---

a
b
由函数
my fun
评估。所有函数都首先计算其参数——只有宏和特殊形式不一定计算其所有参数

但是那些
a
b
值并没有传递给宏——传递给宏的唯一内容是绑定到
cmd
的未赋值sexp。您甚至不在函数中定义
cmd

您需要做的是将
a
b
的值替换为
cmd
sexp。您根本没有展示如何定义/构造
cmd
。使用
a
b
的值构造它,您应该可以

要构造
cmd
sexp,请记住可以使用反引号语法来简化操作,使用逗号语法来传递
a
b
的值。例如

(let((cmd`)(一些有趣的(表达式)(使用)),a和b)))
使用CMD的代码)

这假设您传递给宏的代码不需要变量
a
b
,它只需要它们的值。

当调用函数
my fun
时,参数已经计算过,因此我不清楚您面临的问题是什么

我看到的唯一奇怪的事情是宏不卫生,因此如果您的参数被命名而不是
a
b
,例如
status
status args
,您将遇到麻烦,因为表达式

(do-something <a> <b> results)
(做点什么结果)

将在宏重复使用这些名称的上下文中编译。

您最好也显示宏(或其演示版本),而不仅仅是试图描述它。我真的不知道这意味着什么:
发送命令,就像我(喜欢做某事)在我的乐趣(这没关系)
我同意@phils。尝试显示您迄今为止尝试过的内容--确切的代码。说出它发生了什么,以及您期望/希望发生什么。正如我在问题中提到的,我尝试使用“我的commandsend and reply宏”及其“:reply”部分来定义我自己的回调函数。在回调中,我需要使用一些变量(参见示例,比如我在dosomething中使用的fun变量“a”和“b”)。发生了什么:没有对变量求值,Lisp说没有变量“a”或“b”(可能是动态作用域的原因),因为它在宏展开的地方搜索变量。我想有一个解决方法。与
defmacro
相比,什么是
defmacro*
?Emacs给出了以下内容(使用“描述”函数):defmacro*是一个Lisp宏。(defmacro*名称ARGLIST[DOCSTRING]BODY…)将名称定义为宏。与普通的“defmacro”类似,除了ARGLIST允许完整的公共Lisp约定外,BODY被(块名…)或
(let((cmd`(some…,a',b)))…)
@WillNess包围——是的,可能是这样。
(defun get-id ()
  (send-command-to-process 'getid))
(do-something <a> <b> results)