如何编写Clojure宏来创建多个表达式?

时间:2010-09-21 18:39:47

标签: macros clojure

是否可以在Clojure中编写一个生成多个值或表达式的宏? 对我来说,它看起来是不可能的,至少不是通过使用语法报价模板`(..)。

e.g。从:[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 个答案:

答案 0 :(得分:10)

宏将一个表单扩展为另一个表单,因此您不能让宏返回两个完全独立的表单。但是,您可以让它返回复合形式,例如do语句,它们会做很多事情。

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

对于上面的示例,您可以将宏放在要修改的表单周围:

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

宏被设计为安全的,因此它们无法修改自己范围之外的任何内容。目前,宏获取s表达式,并将其更改为另一个更有用或更有用的s表达式。为了使宏返回两个单独的s表达式,它必须修改其封闭表达式。语法必须完全不同,我不清楚如何用s表达式完成。解决方案是扩展宏的范围以包括它需要修改的所有内容。