【问题标题】:lisp defclass macro problemlisp defclass 宏问题
【发布时间】:2010-12-21 22:25:15
【问题描述】:

一点背景知识,我是一个完全 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)
   )
)

【问题讨论】:

标签: macros lisp common-lisp


【解决方案1】:

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

第一个问题(如何组成符号名):Lisp 宏不会 对 text 进行操作,但对 code 进行操作。在反引号形式中,,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):你可以直接问这个问题,不是吗?有什么限制 你是说?

【讨论】:

  • “不要像剪指甲一样乱扔括号”——如果他不明白你的意思,这句话不会帮助他理解任何事情。哎呀,我使用 Lisp 已经超过 15 年了(而且英语比这长得多),我不认为 明白你的意思。 (人们是否倾向于把指甲剪得离得很远?)
  • @svante:我想说,虽然 STRING-UPCASE 在你的情况下是必要的,但不会 (intern (concatenate 'string (symbol-name class) (symbol-name '-insert ))) 是一个更好的解决方案,因为它甚至可以在使用不同读取表的普通 lisp 环境中工作(例如,没有大小写)?
  • 另一个给您更多灵活性的选项是从字符串读取。这允许您执行以下操作:(read-from-string (format nil "~a-insert" (symbol-name class))。
  • @Vatine:我只是给出了遵循默认约定的示例代码。您的解决方案的缺点是符号 '-insert 也会被拘留。我喜欢 Andrew Myers 的 read-from-string 表单。
  • 我真正的问题是 clsql 和在 ODBC 数据源上插入的问题,插入后获取 auto inc 标识字段。我有一个朋友(真正的 lisp 人)调查了这个问题,他说这是 CLSQL 的一个问题,并且有一个限制,(适用于 mysql,不适用于 ODBC)。他建议使用类似这样的东西,它确实有效,但每次定义一个类时都需要我编写两个类。如果可以避免的话,我不想手动编写它们,因为它们只是略有不同,我希望宏能成为将我保存在这里的候选者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 2021-08-28
相关资源
最近更新 更多