在我的Clojure项目中尝试使用trampoline
优化尾递归时,我遇到了trampoline
函数的一些奇怪行为。
=> (defn f [g] (fn [k & args] #(k (apply g args))))
...
=> (trampoline (f list) println 1 2 3)
(#<core$println clojure.core$println@54e517f6> 1 2 3)
nil
=> (((f list) println 1 2 3))
(1 2 3)
nil
我认为(trampoline (f list) ...)
和((f list) ...)
给出了相同的结果,但正如您在上面所看到的,他们没有。有人会解释这里发生了什么吗?
答案 0 :(得分:2)
好抓!
您应该将此错误报告给Clojure Dev Group或Clojure Issue Tracker。
另请注意,此错误只能通过调用(apply list args)
内的trampoline
并且仅当args
绑定到初始函数的参数列表的尾部时才能重现。
这里的实际问题是Clojure将args
重新绑定到初始函数参数的整个列表。
以下是重现问题的简短示例:
(defn foo [h & ts] (apply list ts))
(trampoline foo 1 2 3) ; => (1 2 3)
(foo 1 2 3) ; => (2 3)
将(apply list ts)
更改为(list ts)
或(apply vector ts)
会使此错误消失。