2024 Clojure 状态调查中分享您的想法!

欢迎!请参阅关于页面以获取有关其工作方式的更多信息。

0
Clojure

以下是 1.8.0 和 1.9.0-alpha14 不编译的错误,两个版本的错误相同。

`
user=> (def fibonacci-1
((fn fib [a b]

(lazy-seq  (cons a  (fib b  (+ a b)))))
0 1))

user=> (filter #(< % 100) fibonacci-1)

算术异常:整数溢出 clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)

user=> (filter #(< % 100) fibonacci-1)

NullPointerException:堆栈溢出异常 clojure.lang.Numbers.ops (Numbers.java:1013)

user=> (def fibonacci-2

     (lazy-cat [0 1] (map + (rest fibonacci-2) fibonacci-2)))

user=> (filter #(< % 100) fibonacci-2)

算术异常:整数溢出 clojure.lang.Numbers.throwIntOverflow (Numbers.java:1501)

user=> (filter #(< % 100) fibonacci-2)
(0 1 1 2 3 5 8 13 21 34 55 89)
`

补丁: 0001-CLJ-2069-cache-exceptions-thrown-during-lazy-seq-rea.patch

提议: 在实现懒惰序列期间缓存抛出的异常,以避免重新运行声明为 ^:once 的主体函数

预筛: Alex Miller

4 个答案

0

评论人:find_my_way

也许我应该使用 take-while 而不是 filter

然而,有人能解释为什么我在第一次运行

(filter #(< % 100) fibonacci-2)

时得到 ArithmeticException,而第二次运行时得到正确的结果吗?

0

评论人:bronsa

NPE 是由以下交互引起的
- 惰性序列在序列部分实现时抛出异常
- 惰性序列使用 ^:once 进行局部清除

lazy-seq 期望 bodyfn 只被运行一次并且结果被缓存,但如果在运行 bodyfn 时抛出异常,当序列第二次尝试实现时,函数将再次运行。然而,如果局部变量已经(即使部分)被清除,这意味着 bodyfn 中的某些局部变量现在将是 nil,而不是持有它们的实际值。

0

评论人:bronsa

附上修复这个问题的补丁

0
参考:https://clojure.atlassian.net/browse/CLJ-2069(由 alex+import 报告)
...