有点背景,我是一个完全没法的人,几周前才开始,但我已经在其他langs开发了多年。逻辑没问题,口齿不清,问题。
我正在尝试编写一个宏,它将为我定义两个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)
)
)
答案 0 :(得分:7)
这里很难开始解释,因为你似乎有一个 整堆误解。
第一个问题(如何组成符号名称):Lisp宏没有
在文本上运行但在代码上运行。以反引号形式,class
计算传递给宏的class
参数的代码,
在这种情况下,很可能是一个类名。之后写另一个符号
这并没有神奇地合并符号名称;为什么要这样?如果你
想要编写一个新的符号名称,你必须构建它:
,(intern (string-upcase (concatenate 'string
(symbol-name class)
"-insert")))
第二个问题(为什么它似乎只扩展了第二部分):
defmacro
表单的内容在隐式progn
中进行评估
(这就是为什么它不会抱怨无效的参数数量
这里)。最后一个表单的返回值是。的返回值
整个defmacro
形式。在这种情况下,返回值是代码
由反引号形式产生。宏定义了一个函数
将表单扩展为新表单;你不能把它扩展成两个
不相关的形式。您必须生成一个包含{。}}表单的progn
表单
你想要的两种形式。
第三个问题(为什么你的代码看起来与Lispers有什么不同 写):不要像指甲剪那样抛出括号。那里 有几个Lisp风格指南在网上飞来飞去。读它们。 Wer die Form beherrscht,kann mit ihr spielen (大致:当你 知道正确的方法,你可以玩它。)
第四个问题(如何绕过感知的限制 clsql):你可以直接问这个问题,不是吗?有什么限制 你的意思是?