jas*_*per 1 lisp macros common-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)
)
)
Run Code Online (Sandbox Code Playgroud)
这里很难开始解释,因为你似乎有一大堆误解.
第一个问题(如何组成符号名称):Lisp宏不对文本进行操作,而是对代码进行操作.在反引号形式中,,class
求值为传递class给宏参数的代码,在这种情况下很可能是类名.在此之后写另一个符号并不会神奇地合并符号名称; 为什么要这样?如果要编写新的符号名称,则必须构造它:
,(intern (string-upcase (concatenate 'string
(symbol-name class)
"-insert")))
Run Code Online (Sandbox Code Playgroud)
第二个问题(为什么它似乎只扩展了第二部分):defmacro表单的内容以隐式方式进行评估progn
(这就是为什么它不会在这里抱怨无效数量的参数).最后一个表单的返回值是整个defmacro表单的返回值.在这种情况下,返回值是由该反引号形式生成的代码.宏定义了一个将表单扩展为新表单的函数; 你不能把它扩展成两种不相关的形式.您必须生成一个progn包含您想要的两个表单的表单.
第三个问题(为什么你的代码与Lispers编写的代码看起来如此不同):不要像括号剪辑那样抛出括号.有几个Lisp风格指南在网上飞来飞去.读它们. Wer die Form beherrscht,kann mit ihr spielen(粗略地说:当你知道正确的方法时,你可以玩它).
第四个问题(如何克服clsql的感知限制):你可以直接问这个问题,不是吗?你的意思是什么?