2016-12-15 6 views
2

私は学習練習としてupdate-inを再実装しようとしており、Clojureのcore.clj GitHubを使用して決定的な答えを見つけています。 (私は見つけるするかどうかはわかりませんが)おそらくClojure:GitHubのupdate-inの2つの異なる定義

(defn update-in 
    ;; metadata removed 
    {:added "1.0" 
    :static true} 
    ([m [k & ks] f & args] 
    (if ks 
    (assoc m k (apply update-in (get m k) ks f args)) 
    (assoc m k (apply f (get m k) args))))) 

(defn update-in 
    ;; metadata removed 
    {:added "1.0" 
    :static true} 
    ([m ks f & args] 
    (let [up (fn up [m ks f args] 
       (let [[k & ks] ks] 
        (if ks 
        (assoc m k (up (get m k) ks f args)) 
        (assoc m k (apply f (get m k) args)))))] 
     (up m ks f args)))) 

そして010864f8ed...ツリーで1:私は、関数の2つの別々の定義は、Masterブランチの1を発見しました、非マスターツリーのバージョンはより新しいものであり、マスターに持ち込まれていません。私はREPLでマスター以外のバージョンを実装しようとしましたが、うまくいくようです。引数が若干異なり、REPLで(doc update-in)を呼び出すと、ツリーの定義と同じ引数が返されます。

マスターの定義がマスター以外のバージョンよりも冗長である理由について少し混乱しています。これは確立されたClojure関数を使用しているようです(つまり、それ以降のバージョンでは導入されていません)。

誰かができます:

  1. は、2つの異なるバージョンが何であるかを明確に?
  2. ツリーのより簡潔なものが(わずかに異なるargであっても)働くとき、マスターのより詳細な定義が存在する理由を説明してください。より効率的に働くようにリファクタリングされましたか?

答えて

2

マスターは実際にはの結果を見て見ることができる最も最近のものです。両方のツリーに対してBlake。 Masterブランチの場合、変更を導入したコミットがimprove update-in perfと表示されます。私はコミットにこれ以上の情報は表示されませんが、それは率直には良くありません。

パッチでは、NULLでないks引数がある場合に行われる処理を変更するローカル関数が導入されています(通常、キーに降順に移動する場合)。 update-inからapplyまでの再帰呼び出しは、upへの直接呼び出しに置き換えられます。

関連する問題