clojure蹦床的奇怪行为

时间:2015-01-07 12:21:08

标签: clojure

在我的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) ...)给出了相同的结果,但正如您在上面所看到的,他们没有。有人会解释这里发生了什么吗?

1 个答案:

答案 0 :(得分:2)

好抓!

您应该将此错误报告给Clojure Dev GroupClojure 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)会使此错误消失。