1

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)
   )
)
3
  • 4
    You might want to have a look at this lisp style guide while you're at it: mumble.net/~campbell/scheme/style.txt Commented Dec 22, 2010 at 11:47
  • 3
    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.html Commented Dec 22, 2010 at 12:31
  • 1
    thanks for the links guys. will check em out Commented Dec 22, 2010 at 14:43

1 Answer 1

7

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?

Sign up to request clarification or add additional context in comments.

6 Comments

"do not throw around parentheses like nail clippings" -- If he doesn't know what you mean, this sentence isn't going to help him understand anything. Heck, I've been using Lisp for over 15 years (and English quite a bit longer than that) and I don't think I understand what you mean. (Do people tend to throw nail clippings far apart a lot?)
@svante: I'd say that while the STRING-UPCASE woulpd be necessary in your case, wouldn't (intern (concatenate 'string (symbol-name class) (symbol-name '-insert))) be a better solution, in that it'd work even in common lisp environments using a different read-table (without, say, case-smashing)?
Another option that gives you a bit more flexibility is read-from-string. This allows you to do something like: (read-from-string (format nil "~a-insert" (symbol-name class)).
@Vatine: I just gave example code that follows the default convention. Your solution has the disadvantage that the symbol '-insert will be interned, too. I like Andrew Myers' read-from-string form.
My real problem is a problem with clsql and inserting on an ODBC datasource, with obtaining the auto inc identity field after the insert. I had a friend(real lisp guy) look into the problem, and he said its a problem with CLSQL,and a limitation,(works for mysql,not for ODBC). He suggested using something like this, which does work, but requires me to write two classes every time i define a class. I dont want to have to write them by hand if if I can avoid it, as they only differ slightly, and I was hoping a macro would be a candidate to save me here.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.