如何避免clojure中重复的函数参数?

如何避免clojure中重复的函数参数?,clojure,Clojure,我有一系列函数,它们都做不同的事情,但传递相同的数据。假设我有以下作为参数向量 [{:keys [x y vx vy x-min x-max y-min y-max] :or {x-min 0 x-max c-width y-min 0 y-max c-height}}] 基本上,这类事情你不想重复多次。我的一个想法是做一些类似的事情 (def func-args [x y z]) (defn func func-args (+ x y z)) 如果我有一个类似的函数,那么我可以重用func

我有一系列函数,它们都做不同的事情,但传递相同的数据。假设我有以下作为参数向量

[{:keys [x y vx vy x-min x-max y-min y-max] :or {x-min 0 x-max c-width y-min 0 y-max c-height}}]
基本上,这类事情你不想重复多次。我的一个想法是做一些类似的事情

(def func-args [x y z])
(defn func func-args (+ x y z))
如果我有一个类似的函数,那么我可以重用func参数。但是,前面示例的第一行抛出一个错误,即无法解析符号x

  • 有没有办法将向量成员保留为符号
  • 有没有比我建议的方法更惯用的方法来减少函数参数代码膨胀

引用向量将使其符号未赋值,但是
defn
要求在定义中使用文字向量,因此这不会像您建议的那样工作

最简单的方法是创建一个宏。宏允许您创建自己的语法。Clojure不鼓励使用这种(回指)宏,因为为您创建符号的宏很容易出现问题

比如:

(def cheight 100)
(def cwidth 100)
(defmacro defx [name & body]
  `(defn ~name [{:keys [~'x ~'y ~'vx ~'vy ~'x-min ~'x-max ~'y-min ~'y-max] 
                 :or {~'x-min 0 ~'x-max ~'c-width ~'y-min 0 ~'y-max ~'c-height}}]
     ~@body))

(defx func (+ x y))

(func {:x 1 :y 2}) ;; 3

下面是另一种方法,它接受函数args spec vector作为宏的参数:

(defmacro defn-args
  [fn-name fn-args & forms]
  `(defn ~fn-name ~(eval fn-args) ~@forms))

(def square-args '[x] )    ; must quote [x] here
(defn-args my-square square-args (* x x))

(my-square 3) 
;=> 9

如果绑定这些向量值,就可以避免出现错误。可能真正的问题是,对于所有这些参数,函数都太复杂了。这是一种非常简洁的方法,在所有情况下只使用一个宏。