Clojure:简单的阶乘导致堆栈溢出 [英] Clojure: Simple factorial causes stack overflow

查看:371
本文介绍了Clojure:简单的阶乘导致堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做错了什么?简单递归几千个调用深度抛出一个 StackOverflowError

What am I doing wrong? Simple recursion a few thousand calls deep throws a StackOverflowError.

如果Clojure递归的限制如此低,我可以依靠它吗?

If the limit of Clojure recursions is so low, how can I rely on it?

(defn fact[x]
  (if (<= x 1) 1 (* x  (fact (- x 1))  )))

user=> (fact 2)
2

user=> (fact 4)
24

user=> (fact 4000)
java.lang.StackOverflowError (NO_SOURCE_FILE:0)


推荐答案

堆栈大小,我明白,取决于你使用的JVM以及平台。如果使用Sun JVM,可以使用 -Xss -XThreadStackSize 参数来设置堆栈大小。

The stack size, I understand, depends on the JVM you are using as well as the platform. If you are using the Sun JVM, you can use the -Xss and -XThreadStackSize parameters to set the stack size.

在Clojure中,递归的首选方法是使用 loop / recur

The preferred way to do recursion in Clojure though is to use loop/recur:

(defn fact [x]
    (loop [n x f 1]
        (if (= n 1)
            f
            (recur (dec n) (* f n)))))

Clojure将为此进行尾调用优化;确保你不会遇到 StackOverflowError

Clojure will do tail-call optimization for this; that ensures that you’ll never run into StackOverflowErrors.

编辑:为了记录,这里是一个Clojure函数返回所有阶乘的延迟序列:

For the record, here is a Clojure function that returns a lazy sequence of all the factorials:

(defn factorials []
    (letfn [(factorial-seq [n fact]
                           (lazy-seq
                             (cons fact (factorial-seq (inc n) (* (inc n) fact)))))]
      (factorial-seq 1 1)))

(take 5 (factorials)) ; will return (1 2 6 24 120)

这篇关于Clojure:简单的阶乘导致堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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