Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning multiple values from a clojure macro

Tags:

macros

clojure

I need to add several methods to a Clojure defprotocol that I am writing for several identical Swing components:

(defprotocol view-methods
  (ok-button-add-action-listener     [this listener])
  (ok-button-set-enabled             [this enabled])
  (ok-button-set-selected            [this selected])
  (cancel-button-add-action-listener [this listener])
  (cancel-button-set-enabled         [this enabled])
  (cancel-button-set-selected        [this selected])
  (other-button-add-action-listener  [this listener])
  (other-button-set-enabled          [this enabled])
  (other-button-set-selected         [this selected]))

Is there any way that I can write a macro that returns all three of the method signatures (xxx-button-add-action-listener, xxx-button-set-enabled, xxx-button-set-selected)?

(defprotocol view-methods
  (add-methods ok)
  (add-methods cancel)
  (add-methods other))

This macro needs to add three items to the growing defprotocol with each invocation.

Can a macro return `~@a-list and expand "in place"?

like image 552
Ralph Avatar asked Jun 18 '11 20:06

Ralph


2 Answers

Yes, you just need to have your macro expand in a (do ...), and the Clojure compiler will thread the do children as a sequence of top level forms.

like image 137
Laurent Petit Avatar answered Nov 12 '22 21:11

Laurent Petit


I believe a macro must expand to a single form - so you can't do this in the exact way you are describing.

However, all is not lost because it would certainly be possible to write this with a macro at the top level that looks something like the following:

(defmacro build-button-protocol [name & method-specs]
    ....)

Which you could use as follows:

(build-button-protocol view-methods
  (add-methods ok)
  (add-methods cancel)
  (add-methods other))
like image 34
mikera Avatar answered Nov 12 '22 22:11

mikera