lisp defclass宏问题

发布于 2024-10-08 17:13:36 字数 707 浏览 0 评论 0原文

一些背景知识,我是一个完全的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

征棹 2024-10-15 17:13:36

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

第一个问题(如何组成符号名称):Lisp 宏不
文本进行操作,但对代码进行操作。在反引号形式中,,class
计算结果为传递到宏的 class 参数中的代码,
在这种情况下很可能是类名。之后再写一个符号
这不会神奇地合并符号名称;为什么要这样呢?如果你
想要组成一个新的符号名称,你必须构造它:

,(intern (string-upcase (concatenate 'string
                                     (symbol-name class)
                                     "-insert")))

第二个问题(为什么它似乎只扩展第二部分):
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:

,(intern (string-upcase (concatenate 'string
                                     (symbol-name class)
                                     "-insert")))

Second question (why it seems to expand only the second part): the
contents of a defmacro form are evaluated in an implicit progn
(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 code
produced 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 the
two 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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文