有没有办法在Clojure中定义一个自动尾部调用优化的函数?
例如:
(defrecur fact [x]
(if (= x 1)
1
(* x (fact (dec x)))))会在内部翻译成类似这样的内容:
(defn fact [x]
(loop [n x f 1]
(if (= n 1)
f
(recur (dec n) (* f n)))))你能告诉我这样的东西是不是已经存在了?
发布于 2012-04-18 23:43:26
简短的回答是“不”。
稍微长一点的答案是,Clojure被故意设计成需要明确指示需要尾部调用优化的地方,因为JVM本身并不支持它。
顺便说一句,您可以在不使用loop的情况下使用recur,因此不需要更多的输入,例如:
(defn func [x]
(if (= x 1000000)
x
(recur (inc x))))更新,4月29日:
Chris Frisz一直在与Dan Friedman合作一个研究项目,虽然目前还没有人声称它是“答案”,但这个项目既有趣又有前途。克里斯最近做了一个关于这个项目和he's posted it on his blog的非正式演讲。
发布于 2012-04-18 23:45:19
据我所知,在Clojure中没有自动生成尾递归的方法。
有一些使用递归而不使用循环的函数示例。在不溢出堆栈的情况下重复该工作。这是因为这些函数都是精心编写的,以便使用惰性序列。
下面是一个用手写函数替换flatten的示例。这个例子来自于http://yyhh.org/blog/2011/05/my-solutions-first-50-problems-4clojure-com
(fn flt [coll]
(let [l (first coll) r (next coll)]
(concat
(if (sequential? l)
(flt l)
[l])
(when (sequential? r)
(flt r)))))https://stackoverflow.com/questions/10212928
复制相似问题