循环重复是否有可能引发StackOverflowError? [英] How is it possible that loop-recur throws a StackOverflowError?

查看:59
本文介绍了循环重复是否有可能引发StackOverflowError?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试实现chainl1的尾递归版本,但是即使使用循环递归,它也会引发StackOverflowError.那怎么可能?我该怎么做才能改变呢?

I´ve been trying to implement a tail-recursive version of chainl1, but even with the loop-recur it throws a StackOverflowError. How is that possible and what can i do to change that?

(defn atest [state]
  (when-not (and (= "" state) (not (= (first state) \a))) 
      (list (first state) (. state (substring 1)))))
(defn op [state]
  (when-not (and (= "" state) (not (= (first state) \a)))
    (list #(list :| %1 %2) (. state (substring 1)))))
(defn chainl1-helper [x p op]
  (fn [state]
    (loop [x x
           state state]
      (if-let [xs (op state)]
        (when-let [xs2 (p (second xs))]
          (recur ((first xs) x (first xs2)) (second xs2)))
        (list x state)))))

(defn chainl1 [p op]
  (fn [state]
    (when-let [[v s] (p state)]
      ((chainl1-helper v p op) s))))
(def test-parse (chainl1 atest op))
(defn stress-test [n] (test-parse (apply str (take n (interleave (repeat "a") (repeat "+"))))))
(stress-test 99999)

推荐答案

其打印出使堆栈崩溃的最终结果所以是REPL而不是您的代码.

its printing the final result that blows the stack so it's the REPL not your code.

(count (stress-test 99999))

完成

堆栈跟踪具有重复多次的这种模式:

the stack trace has this pattern repeating many times:

 13:    core_print.clj:58 clojure.core/print-sequential
 14:    core_print.clj:140 clojure.core/fn
 15:      MultiFn.java:167 clojure.lang.MultiFn.invoke

LDomagala指出了打印级作为防止此类崩溃的安全措施

LDomagala pointed out print-level as a safety against this sort of crash

user>  (set! *print-level* 20)
20
user> (stress-test 9999)
((:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f (:f # \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) \a) "")
user> 

这篇关于循环重复是否有可能引发StackOverflowError?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆