2016-11-23 55 views
3

我有一系列的功能,都做不同的事情,但传递相同的数据。假设我有以下参数向量。如何避免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-args,如果我有类似的功能。但是,前面示例的第一行引发了一个符号x无法解析的错误。

  • 有没有办法让矢量成员作为符号?
  • 有没有比我建议的方法更加通俗的方法来完成函数参数代码膨胀减少?
+0

如果绑定的矢量值,你”会避免你遇到的错误。 – jmargolisvt

+2

也许真正的问题在于,对于所有这些论点,你的功能太复杂了。 –

回答

2

这里是做这件事的另一种方式,接受函数参数符合规范向量作为参数传递给宏:

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

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

(my-square 3) 
;=> 9 
+0

这是一个非常简洁的方法,只对所有情况使用一个宏。 –

5

引用矢量会使其符号未被评估,但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}}] 
    [email protected])) 

(defx func (+ x y)) 

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