(message ...) already accepts a format string, but if it didn’t it would be easy to add that functionality with a macro.
(defmacro message* (str &rest vars) `(message (format ,str ,@vars)))
But it only accepts a single format string. Perhaps I would like to concatenate a few strings or variables together. But then if I only pass a string in, I want that to work correctly too. Macros can generate different code if you pass in different types. (I fix the underlying format* so I can use it in message, error, etc.)
(defmacro format* (str &rest vars) (if (stringp str) `(format ,str ,@vars) `(format (concat ,@(mapcar #'identity str)) ,@vars)))
The result looks a little strange. When I see an unquoted list, the first element has to be the name of the function that is being called.
(defvar x "xxx") (format* (x " " "%s") 1) ;; --> "xxx 1"
Can I just interject the thought that a language with a macro syntax like this has no business ever dismissing perl as “ugly”?
Whenever I play around with elisp macros I can get them to do about half of what I want, and then I give up on them for another six months (my last problem, if I remember right, was I couldn’t figure out how to get a macro to use a symbol passed inside a variable).
Hi Joseph,
I’m afraid I can’t agree with you there. Lisp’s macro syntax looks fine to me. It is certainly a heck of a lot more beautiful than the (turing complete) C++ template system and somewhat debuggable too. Having said that, I don’t find perl ugly either.
Maybe the reason you don’t like is that you’re not sufficiently familiar with it. What would you prefer it to look like (maybe you could macroize a new macro system!)
From the description of what you were trying to do, it sounds like you were trying to do something that required runtime information – what a variable was set to, when macros operate at compile time. If you need to extract the symbol value, you need to expand to something like `(symbol-value ,variable).