来自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)))))
ret的let绑定实现了什么?为什么不只是:
(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))))
基本测试(在ClojureCLR中)似乎表明后者工作正常,我找不到任何说明前者使用的文件。有线索吗?
谢谢,加里
答案 0 :(得分:2)
您的版本应该无法编译,因为没有足够的参数传递给recur
(在这种情况下需要四个)。存在let
以将传递给第一个主体(3-arity)的第一对键/值的关联结果绑定为ret
。如果先使用recur
kvs
= nil
使用nnext
自行调用第二个正文(因为recur
表单中的(if kvs ..)
为第四个参数)ret
将失败,并且可以简单地返回kvs
。如果可能发生更多{{1}}尾递归。