Comma operator and macros

Discussion of Common Lisp
Post Reply
lrodrig
Posts: 17
Joined: Thu Sep 16, 2010 4:52 pm

Comma operator and macros

Post by lrodrig » Sat Jun 11, 2011 10:04 am

Hi,

I have a macro that creates a clausure like this:

Code: Select all

(defmacro object-mult (atr1 atr2)
  ` (let ((atr1 ,atr2) (atr2 ,atr2))
      (lambda (x) (* atr1 atr2))))
The thing is that I'm trying to implement another macro that automatically produces the code shown in the example above . The macro skeleton would be something like:

Code: Select all

(defmacro generate-class (name attributes code)
 `(defmacro ,name (,@attributes)
   (let ...)))
This way, I could call "generate-class" with the arguments atr1, atr2 and '(* atr1 atr2) and the macro will expand to what is shown in the first example. The problem is that I don't know how to specify the "comma" operators inside "generate-class" to obtain the symbols ",atr1" and ",atr2" in the let part in "object-mult". I came up with a solution consisting in transforming the symbols into strings and then inserting the "," at the beginning of the string. Then I had to obtain a valid symbol from the string by calling (intern ...). I know how to get a proper keyword symbol from a string using "KEYWORD" as the second argument to intern. Is there something similar for strings starting with ","?

Thanks in advance,
Luis

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Comma operator and macros

Post by ramarren » Sat Jun 11, 2011 1:11 pm

Backquote-comma mechanism is just a shortcut syntax over list operations. You can always transform `(a ,b) into (list 'a b), although obviously the backquote saves much more typing with nested structures. The important consequence of this is that backquote is not a macro related mechanism, although it is most commonly encountered for that purpose.

While the backquotes can be nested, with the outermost comma corresponding to innermost backquote, it often is simpler to just generate the needed code using functions, and then just write a macro using those function to generate the expansion.

Konfusius
Posts: 62
Joined: Fri Jun 10, 2011 6:38 am

Re: Comma operator and macros

Post by Konfusius » Sat Jun 11, 2011 1:35 pm

The backquote reader macro is confusing and hard to explain. I'll just give you an example of how it's done hoping you can figure it out by yourself:

Code: Select all

(defmacro make-mul-macro (name lambda-list)
  `(defmacro ,name ,lambda-list
	  `(* ,,@lambda-list)))

(make-mul-macro test (x y z))

(print (test 2 3 4))
The comma before the comma-at "neutralizes" the inner backquote so ,@lambda-list behaves as if there wasn't an inner backquote.

lrodrig
Posts: 17
Joined: Thu Sep 16, 2010 4:52 pm

Re: Comma operator and macros

Post by lrodrig » Sun Jun 12, 2011 12:19 am

Thanks a lot!

Kompottkin
Posts: 94
Joined: Mon Jul 21, 2008 7:26 am
Location: München, Germany
Contact:

Re: Comma operator and macros

Post by Kompottkin » Tue Jun 14, 2011 5:34 am

Also note that, while I don't know what it is you're trying to accomplish, and higher-order macrology (i.e., macro-generating macros) is generally quite fine and sometimes necessary, the particular case you cited can easily be handled without this kind of complexity, since object-mult doesn't seem to need to be a macro at all:

Code: Select all

(defun object-mult (atr1 atr2)
  (lambda (x) (* atr1 atr2)))
(I'm assuming that “(atr1 ,atr2)” was a typo in your code.)

Post Reply