Как написать макрос Clojure для создания более одного выражения? - PullRequest
7 голосов
/ 21 сентября 2010

Можно ли написать макрос в Clojure, который генерирует более одного значения или выражения? Для меня это выглядит невозможным, по крайней мере, с помощью шаблона синтаксической кавычки `(..).

например. от: [1 4] через [1 (mr 2 3) 4] до [1 2 3 4]

или от:

(do
  (prn 1)
  (prn 4))

с помощью:

(do
  (prn 1)
  (mr 2 3)
  (prn 4))

до:

(do
  (prn 1)
  (prn 2)
  (prn 3)
  (prn 4))

1 Ответ

10 голосов
/ 21 сентября 2010

Макрос расширяет одну форму в другую, поэтому вы не можете получить макрос, возвращающий две полностью независимые формы. Однако вы можете заставить его возвращать составные формы, такие как do операторы, которые делают кучу вещей.

(defmacro foo [n]
  `(do ~@(map #(list println %) n)))

В приведенном выше примере вы можете поместить макрос вокруг формы, которую вы хотите изменить:

(expand-mr
 (do 
   (prn 1)
   (mr 2 3)
   (prn 4)))
Макросы

разработаны так, чтобы быть безопасными, и поэтому они не могут ничего изменять вне своей области видимости. В настоящее время макрос получает s-выражение и превращает его в другое более полезное или полезное s-выражение. Для того чтобы макрос мог вернуть два отдельных s-выражения, ему необходимо изменить его включающее выражение. Синтаксис должен быть радикально другим, и я не понимаю, как это будет сделано с s-выражениями. Решение этой проблемы состоит в том, чтобы расширить область действия макроса, включив в него все, что нужно изменить.

...