clojure – 为什么我得到stackoverflow?

我一直在和Clojure一起玩,我设法炸掉了筹码.在这段代码中,我只使用recur进行递归.我正在进行大量的连接(请注意下面的跟踪调用concat).我试图在所有连接列表上执行操作,因为这些是懒惰的,我希望它们在我进行时进行评估.我仍然得到堆栈溢出.这是跟踪.我认为这可能是一个普遍的问题,而且有更多经验黑客攻击的人可以指出我正确的方向.

这是造成问题的代码段.

(defn move-split [[xs ys]] (doall (concat (list (concat xs (list (first ys))))  (list (next ys)))))

由于stackoverflow,我把doall放在那里,但仍然没有解决问题.

(defn move-split [[xs ys]] (doall (concat (list (doall (concat xs (list (first ys))))  ) (doall (list (next ys)))   )))

注意额外的doalls?在这里,我称之为concat,我通过doall过滤结果. Stackoverflow消失了.

doall似乎不是递归的.这是嵌套列表,也是concat的结果,不会被评估.你怎么看?

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at jline.ConsoleRunner.main(Unknown Source)
Caused by: java.lang.StackOverflowError (bubble_sort2.clj:0)
    at clojure.lang.Compiler.eval(Compiler.java:5440)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.Compiler.loadFile(Compiler.java:5820)
    at clojure.main$load_script.invoke(main.clj:221)
    at clojure.main$script_opt.invoke(main.clj:273)
    at clojure.main$main.doInvoke(main.clj:354)
    at clojure.lang.RestFn.invoke(RestFn.java:409)
    at clojure.lang.Var.invoke(Var.java:365)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.main.main(main.java:37)
    ... 5 more
Caused by: java.lang.StackOverflowError
    at clojure.core$seq.invoke(core.clj:122)
    at clojure.core$concat$fn__3450.invoke(core.clj:599)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:56)
    at clojure.lang.RT.seq(RT.java:450)
    at clojure.core$seq.invoke(core.clj:122)
    at clojure.core$concat$fn__3450.invoke(core.clj:599)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:56)
    at clojure.lang.RT.seq(RT.java:450)
    at clojure.core$seq.invoke(core.clj:122)
    at clojure.core$concat$fn__3450.invoke(core.clj:599)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:56)
    at clojure.lang.RT.seq(RT.java:450)
    at clojure.core$seq.invoke(core.clj:122)
    at clojure.core$concat$fn__3450.invoke(core.clj:599)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:56)
    at clojure.lang.RT.seq(RT.java:450)
    at clojure.core$seq.invoke(core.clj:122)
    at clojure.core$concat$fn__3450.invoke(core.clj:599)
你正在连续堆积一堆懒惰的操作,构建一个像这样的表达式

(concat (concat (concat ... [3]) [2]) [1])

或类似的.为了确定结果列表中的第一个元素,编译器必须深入研究您给出的这些函数堆栈.尝试构造您的代码,以便不会发生这种情况,或者每隔一段时间抛出一次(doall)以强制执行急切/严格的计算.我不能仅仅通过堆栈跟踪来了解更多细节 – 代码会有所帮助.

相关文章
相关标签/搜索