1
votes

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)
   )
)
1
You might want to have a look at this lisp style guide while you're at it: mumble.net/~campbell/scheme/style.txtShaun
Strongly agree with the suggestion of looking at a Lisp style guide. This chapter on PCL might help clear up some of your misconceptions about how macros work. gigamonkeys.com/book/macros-defining-your-own.htmlasm
thanks for the links guys. will check em outjasper

1 Answers

7
votes

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?