lisp defclass宏问题
一些背景知识,我是一个完全的 lisp 菜鸟,几周前才开始,但多年来我一直在其他语言上进行开发。逻辑没问题,口齿不清有问题。
我正在尝试编写一个宏来定义两个 clsql 类,以解决库的问题。我希望这些类被命名为 x
和 `x-insert`` ,所以在宏中我希望宏计算 x-insert 的符号名称,但我有做这件事有困难。我的尝试如下,但我被两件事难住了。
我如何让它创建类名。如果我删除 ,class -insert
中的空格,它不会评估,这是我理解的,所以我想我缺少一些简单的方法来告诉它忽略空格,并将名称创建为单个词,第二个问题是让它创建两个类,而不是一个类,因为它只是从我使用宏扩展所看到的扩展宏的最后一部分。
也许我的做法完全错误,所以请随意将我踢向正确的方向。
(defmacro gen-pair (class base-slots pkey-slot base-table)
`(clsql:def-view-class ,class -insert()
(
,base-slots
)
(:base-table ,base-table)
)
`(clsql:def-view-class ,class (,class -insert)
(
,pkey-slot
)
(:base-table ,base-table)
)
)
Bit of background, I'm a total lisp noob, only started a few weeks ago, but I've been developing in other langs for years. Logic no problem, lisp, problem.
I'm trying to write a macro that will define two clsql classes for me to get around a problem with the library. I'd like the classes to be named x
and `x-insert`` , so within the macro I'd like the macro to compute the symbol name of x-insert, but I'm having difficulity doing this. My attempt is below, but i'm stumped on two things.
How do I get it to create the class names. If i remove the space in ,class -insert
, it wont eval, which I understand, so I presume I'm missing some straightforward way to tell it to ignore the space,and create the name as a single word, and the second problem is getting it to create two classes, not one, as its only expanding the last part of the macro from what I can see using macro expand.
Perhaps I'm going about this the wrong way altogether, so feel free to kick me in the right direction.
(defmacro gen-pair (class base-slots pkey-slot base-table)
`(clsql:def-view-class ,class -insert()
(
,base-slots
)
(:base-table ,base-table)
)
`(clsql:def-view-class ,class (,class -insert)
(
,pkey-slot
)
(:base-table ,base-table)
)
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
很难在这里开始解释,因为你似乎有一个
一大堆误解。
第一个问题(如何组成符号名称):Lisp 宏不
对文本进行操作,但对代码进行操作。在反引号形式中,
,class
计算结果为传递到宏的
class
参数中的代码,在这种情况下很可能是类名。之后再写一个符号
这不会神奇地合并符号名称;为什么要这样呢?如果你
想要组成一个新的符号名称,你必须构造它:
第二个问题(为什么它似乎只扩展第二部分):
defmacro
形式的内容在隐式progn
中进行计算(这就是为什么它不会抱怨参数数量无效
这里)。最后一个表单的返回值是
整个
defmacro
形式。在这种情况下,返回值是代码由该反引号形式产生。宏定义了一个函数,
将一种形式扩展为一种新形式;你不能将它扩展为两个
不相关的形式。您必须生成一个
progn
表单,其中包含您想要的两种形式。
第三个问题(为什么你的代码看起来与 Lispers 的代码如此不同)
write):不要像剪指甲一样乱扔括号。那里
网上流传着一些 Lisp 风格的指南。阅读它们。
Wer die Form beherrscht, kann mit ihr spielen(大致上:当您
知道正确的方法,你就可以玩它)。
第四个问题(如何克服感知到的局限性)
clsql):你可以直接问这个问题,不是吗?有什么限制
你的意思是?
It is difficult to begin an explanation here, since you seem to have a
whole stack of misconceptions.
First question (how to compose symbol names): Lisp macros do not
operate on text but on code. In a backquote form,
,class
evaluates to the code passed into the
class
parameter of the macro,most likely a class name in this case. Writing another symbol after
that does not magically merge the symbol names; why should it? If you
want to compose a new symbol name, you have to construct it:
Second question (why it seems to expand only the second part): the
contents of a
defmacro
form are evaluated in an implicitprogn
(that is why it does not complain about an invalid number of arguments
here). The return value of the last form is the return value of the
whole
defmacro
form. In this case, the return value is the codeproduced by that backquote form. A macro defines a function that
expands a form into a new form; you cannot expand it into two
unrelated forms. You have to produce a
progn
form that contains thetwo forms you want to have.
Third question (why your code looks so different from what Lispers
write): do not throw around parentheses like nail clippings. There
are several Lisp style guides flying around on the net. Read them.
Wer die Form beherrscht, kann mit ihr spielen (roughly: when you
know the proper way, you can play with it).
Fourth question (how to come around the perceived limitation of
clsql): you could ask that question directly, no? What limitation do
you mean?