lisp defclass宏问题

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)

Sva*_*nte 7

这里很难开始解释,因为你似乎有一大堆误解.

第一个问题(如何组成符号名称):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的感知限制):你可以直接问这个问题,不是吗?你的意思是什么?

  • "不要像钉子一样乱扔括号" - 如果他不知道你的意思,这句话不会帮助他理解任何事情.哎呀,我已经使用Lisp超过15年了(英语相当长一点),我不认为*我*明白你的意思.(人们往往把指甲剪得很远吗?) (2认同)
  • @svante:我想说虽然在你的情况下STRING-UPCASE woulpd是必要的,但是(实习(串联'string(符号名称类)(符号名称'-insert)))不是更好的解决方案,因为它甚至可以在使用不同读表的普通lisp环境中工作(没有,例如,案例粉碎)? (2认同)