编辑:这不是减少或减少功能的问题。我隐藏了clojure.core/range
函数。
我有一个功能
(defn- roundfn [[xi ci bi oi :as state] r]
(let [[xn cn bn] (newstate [xi ci bi] 0)
exfn (word<-x xn)]
[xn cn bn
(into oi
[(exfn [6 3 6 1])
(exfn [4 1 4 7])
(exfn [2 7 2 5])
(exfn [0 5 0 3])])]))
其中x1,x2和x4本身就是向量。 x3是一个值。
当我减少此功能时
(reduce roundfn [[][] 0 []] (range 3))
或
(reduce roundfn [[][] 0 []] (vec (range 3)))
我收到了IndexOutOfBoundsException clojure.lang.PersistentVector.arrayFor (PersistentVector.java:107)
当我减少此功能时
(reduce roundfn [[][] 0 []] [0 1 2])
按预期工作
答案 0 :(得分:2)
(正在处理this version of the source - 链接到该问题评论中提到的文件的当前版本。)
首先,在您列出的所有情况下,运行代码会在我的REPL中产生异常,包括文字[0 1 2]
情况。如果事实并非如此,那将是惊人的。 (注意:我使用rabbit-round
代替roundfn
,因为这是在GitHub上的源代码中找到的问题文本中引用的函数的名称。)
问题的来源如下(根据问题评论中给出的完整来源的链接):
问题文本中列为roundfn
的函数在源代码中称为rabbit-round
。有问题的电话是(reduce rabbit-round [[] [] 0 []] [0 1 2])
。
reduce
比使用初始参数调用rabbit-round
;其中发出了对roundfn
的调用(roundfn
是原始来源中的单独函数):(roundfn [[] [] 0] 0)
。在这里抛出异常。
roundfn
是两个函数的组合;已经第一个成为问题的根源:(update-counter-system [[] [] 0] 0)
抛出。
使用reduce
作为缩减功能,在那里进行了进一步的counter-system-round
调用。首次应用后者时抛出异常:(counter-system-round [[] 0] 0)
。
查看counter-system-round
我们发现它尝试在第一行计算(nth c round)
。此时,c
绑定到[]
(空向量),round
绑定为0
。因此,此调用等于(nth [] 0)
并正确抛出IndexOutOfBoundsException
。
答案 1 :(得分:0)
我用clojure.core\range
解构
[lower upper :as range]
函数
以下是无效的版本
(generate-keystream [_ {:keys [ss] :as initmap} [lower upper :as range]]
(let [ns (conj ss [])]
(reduce rabbit-round ns (range 3))))
以下按预期方式工作(请注意更改为:as rng
而不是:as range
)
(generate-keystream [_ {:keys [ss] :as initmap} [lower upper :as rng]]
(let [ns (conj ss [])]
(reduce rabbit-round ns (range 3))))
这解释了为什么(range 3)
和(vec (range 3))
都不起作用,但[0 1 2]
做了。前两个是在原始代码中评估([0 0] 3)
和(vec ([0 0] 3))
,而[0 1 2]
正在评估[0 1 2]
并成功。
经验教训。不要影子功能
作为旁注,这也有效......
(generate-keystream [_ {:keys [ss] :as initmap} [lower upper :as range]]
(let [ns (conj ss [])]
(reduce rabbit-round ns (clojure.core/range 3))))