2016-11-23 6 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}}] 

基本的に2回以上繰り返す必要がないタイプのものです。私が持っていた考えのようなものをすることでした。

(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

これはすべての場合に1つのマクロのみを使用する非常に簡潔な方法です。 –

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 
関連する問題