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

Ste*_*fan 7 macros clojure

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

例如来自:[1 4]via [1 (mr 2 3) 4]to[1 2 3 4]

或来自:

(do
  (prn 1)
  (prn 4))
Run Code Online (Sandbox Code Playgroud)

通过:

(do
  (prn 1)
  (mr 2 3)
  (prn 4))
Run Code Online (Sandbox Code Playgroud)

至:

(do
  (prn 1)
  (prn 2)
  (prn 3)
  (prn 4))
Run Code Online (Sandbox Code Playgroud)

Art*_*ldt 10

宏将一个表单扩展为另一个表单,因此您不能让宏返回两个完全独立的表单.但是,您可以让它返回复合形式,例如do执行大量操作的语句.

(defmacro foo [n]
  `(do ~@(map #(list println %) n)))
Run Code Online (Sandbox Code Playgroud)

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

(expand-mr
 (do 
   (prn 1)
   (mr 2 3)
   (prn 4)))
Run Code Online (Sandbox Code Playgroud)

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