Clojure:使用宏或def的函数参数/签名

时间:2012-10-17 15:06:27

标签: function clojure arguments definition reduce

我有许多相同长签名的功能(为简单起见,这里简称):

(defn f 
      [x & {:keys [a b c d e f g h]
            :or [a false b false c false d false e false f false g false h false]}]
      a)

我希望事先使用宏,函数甚至def来存储这个共同的签名:

(def args `[a b c d e f g h])

(defn args [] `[a b c d e f g h])

(defmacro args [] `[a b c d e f g h])

但是所有这些,当我插入

(defn f 
      [x & {:keys (args)
            :or [a false b false c false d false e false f false g false h false]}]
      a) 

最终出现了像

这样的错误
CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:1) 

所以我的两个问题是:

  1. 有没有办法定义和使用这样的常见args

  2. 如果可以定义此类args,我还想减少它以获得:or参数:[a false b false c false d false e false f false g false h false]。怎么做? (我要问的是args的工作定义可能很奇怪,这不再是直截了当的。)

1 个答案:

答案 0 :(得分:6)

问题是defn中参数向量内的东西没有得到评估。但是,您可以定义自己的defn版本,如下所示:

user=> (defmacro mydefn [name & body] `(defn ~name ~'[a b c] ~@body))
#'user/mydefn
user=> (mydefn f (+ a b))
#'user/f
user=> (f 1 2 4)
3

请注意参数需要~'。否则,syntax-quote(`)会将符号限定为user.a等等。