2010-09-21 64 views
7

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

例如从:经由[1 (mr 2 3) 4][1 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)) 

回答

10

甲宏扩展一种形式到另一种形式,所以你不能有一个宏返回两个完全独立的f奥姆斯。然而,你可以让它返回复杂的形式,如do陈述,做一堆事情。

(defmacro foo [n] 
    `(do [email protected](map #(list println %) n))) 

对于你上面的例子,你可以把宏观周围的形式要修改:

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

宏的设计是安全的,因此他们不能对自己以外的任何修改范围。目前,一个宏得到一个s表达式,并将其变成另一个更有用或有用的s表达式。为了让宏返回两个单独的s表达式,它将不得不修改它的包含表达式。语法必须有根本的不同,我不清楚s表达式是如何实现的。解决方案是扩大宏的范围以包含需要修改的所有内容。

+0

谢谢亚瑟!我已经在期待这个答案,但很确定。 – Stefan 2010-09-21 18:55:44

+0

但是你真的可以给我一个例子:返回两个独立窗体的宏如何导致安全问题,但是否安全?我认为范围仍然是一样的。 – Stefan 2010-09-21 22:07:15

+0

我对此使用的术语'安全'宽松地抱歉。我会编辑以扩展。 – 2010-09-21 22:47:42

相关问题