Clojure 是我第一次涉足 lisp 世界。我决定尝试一个简单的递归函数,它将一个数字提高到整数幂。很简单。
(defmulti pow #(compare %2 0))
(defmethod pow 0 [a n] 1)
(defmethod pow 1 [a n] (* a (pow a (dec n))))
(defmethod pow -1 [a n] (/ 1 (pow a (* -1 n))))
如果你只传递整数幂,它就可以正常工作。但是当我使用它来提升到足够大的功率时,我得到了堆栈溢出(可以预见)。
问题是,我怎样才能知道函数在死前的递归深度?大致了解我可以递归多深的一种方法是执行以下操作:
(defn max-depth [n]
(try
(max-depth (inc n))
(catch StackOverflowError err (do
(printf "%s at %d\n" err n)
n)
)))
(Clojure 是我第一次尝试 lisp,所以我真的不知道如何让代码看起来可读。)这段代码只是无限递归,直到它溢出堆栈,然后返回在它爆炸之前发生的递归次数。这只能让我大致了解我可以走多远……这种方法存在很多问题。
我可以做的另一件事是捕获异常并尝试自己展开堆栈......但我真的看不到从异常中获取我想要的信息的方法。在http://docs.oracle.com/javase/6/docs/api/java/lang/StackOverflowError.html上查看StackOverflowError 的 javadoc我看到了一些看起来很有希望的方法,但没有任何结果。看。
我尝试运行 (count (.getStackTrace error)) ,其中错误是我捕获的堆栈溢出,但结果仅为 1024,因为“在某些情况下,可能会省略堆栈帧”。所以那没有用。
我能想到的唯一另一件事是在连续更大的指数上运行 pow,但这并不能真正告诉我调用堆栈有多深,它只告诉我可以提高到多大的指数(因为函数调用其他函数,两个答案不一样)。
我也不知道在 java 中有什么方法可以做到这一点,但如果有的话,那么这个答案也可能会有所帮助。
有任何想法吗?谢谢,--斯科特