Возврат нескольких значений из макросов clojure - PullRequest
8 голосов
/ 19 июня 2011

Мне нужно добавить несколько методов в Clojure defprotocol, который я пишу для нескольких идентичных компонентов Swing:

(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]))

Есть ли способ написать макрос, который возвращает все три изсигнатуры методов (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))

Этот макрос должен добавить три элемента к растущему defprotocol с каждым вызовом.

Может лимакрос вернуть `~@a-list и развернуть "на месте"?

Ответы [ 2 ]

10 голосов
/ 19 июня 2011

Да, вам просто нужно развернуть макрос в (do ...), и компилятор Clojure будет обрабатывать дочерние элементы do как последовательность форм верхнего уровня.

1 голос
/ 19 июня 2011

Я считаю, что макрос должен расширяться до одной формы - поэтому вы не можете сделать это точно так, как вы описываете.

Однако, еще не все потеряно, потому что, безусловно, можно написать это с помощью макроса на верхнем уровне, который выглядит примерно так:

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

Что вы можете использовать следующим образом:

(build-button-protocol view-methods
  (add-methods ok)
  (add-methods cancel)
  (add-methods other))
...