简体   繁体   English

通过let绑定进行Clojure递归

[英]Clojure recursion through let binding

From core.clj, the definition of assoc (trimmed of metadata etc) 来自core.clj,assoc的定义(修剪元数据等)

(def assoc
 (fn assoc
   ([map key val] (. clojure.lang.RT (assoc map key val)))
   ([map key val & kvs]
    (let [ret (assoc map key val)]
      (if kvs
        (if (next kvs)
          (recur ret (first kvs) (second kvs) (nnext kvs))
          (throw (IllegalArgumentException. "assoc expects even no of args...")))
    ret)))))

what does the let binding of ret achieve? ret的let绑定实现了什么? Why is it not just: 为什么不只是:

(def assoc
 (fn assoc
   ([map key val] (. clojure.lang.RT (assoc map key val)))
   ([map key val & kvs]
      (if kvs
        (if (next kvs)
          (recur (first kvs) (second kvs) (nnext kvs))
          (throw (IllegalArgumentException. "assoc expects even no of args...")))
    ret))))

Rudimentary testing (in ClojureCLR) seemed to indicate the latter works ok, and I can't find any documentation indicating the use of the former. 初步测试(在ClojureCLR中)似乎表明后者工作正常,我找不到任何说明前者使用的文件。 Any clues? 有线索吗?

Thanks, gary 谢谢,加里

Your version should fail to compile because not enough arguments are passed to recur (four are needed in this case). 您的版本应该无法编译,因为没有足够的参数传递给recur (在这种情况下需要四个)。 The let exists to bind the result of association of the first pair of key/values passed to the first body (3-arity) as ret . 所述let存在于第一对传递到所述第一主体(3-元数)作为键/值的关联的结果结合ret In case the second body was invoked by itself earlier using recur with kvs = nil (as a result of calling nnext in the recur form as the fourth argument) (if kvs ..) will fail and ret can simply be returned. 如果第二个主体本身早先使用recurkvs = nil调用( nnextrecur形式中调用nnext作为第四个参数) (if kvs ..)将失败并且可以简单地返回ret If there are more kvs tailrecursion can happen. 如果有更多的kvs尾随时间可以发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM