0

I'm trying to create a macro (bar) that should be used like this:

(let ((my-var "foo"))
   (bar ("some")
        :buzz (lambda () (format t "~a~%" my-var))))

The macro should basically just FUNCALL the lambda with taking MY-VAR into account.

What I've come up with is this:

(defmacro bar ((thing) &body body)
   `(funcall (coerce (getf (list ,@body) :buzz) 'function)))

This works, it prints "foo". But I'd like to know if this is how this is done or if there is a better way of doing this.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
Manfred
  • 423
  • 3
  • 9

1 Answers1

2

Well, for a start if you don't need the extra, unused argument, then this is just funcall, since (lambda ...) denotes a function.

(let ((my-var "foo"))
  (funcall (lambda () (format t "~a~%" my-var))))

So even if you didn't want to call this funcall you could write it as a function, not a macro: it's not doing any code transformation. But presumably you actually do need this extra argument, and you are intending to use it for some purpose in the expansion, so what you need then is a macro which takes keyword arguments and just expands into a suitable funcall form:

(defmacro bar ((thing) &key (buzz '(lambda ())))
  (declare (ignore thing))
  `(funcall ,buzz))
  • 1
    Thanks. Indeed I need the unused argument. This is just a simplified example from a larger surrounding setup. I didn't actually think about the &key arguments. But that would mean the lambda parameter are within the lambda list of the macro definition, not the body. I need to think about if this is how the macro should be used. – Manfred Apr 23 '21 at 10:30
  • 1
    @Manfred: you can have both: `(defmacro foo ((thing) &body x &key ...)` is fine. It does mean the body is constrained to be keyword-value pairs (you can use `&allow-other-keys` to say that it can be *any* such pairs). I suspect as you say you need to think about what syntax you are aiming at (I often have this problem!) –  Apr 23 '21 at 10:43
  • OK. This seems to work as I want with &key after &body. – Manfred Apr 23 '21 at 14:44