This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

Comma operator and macros

5 posts · 2288 views

Hi,

I have a macro that creates a clausure like this:
(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:
(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

Re: Comma operator and macros

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.

Re: Comma operator and macros

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:
(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.

Re: Comma operator and macros

Thanks a lot!

Re: Comma operator and macros

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:
(defun object-mult (atr1 atr2)
  (lambda (x) (* atr1 atr2)))
(I'm assuming that “(atr1 ,atr2)” was a typo in your code.)