用于在定义中自我调用递归函数的通用函数

时间:2011-05-17 14:10:14

标签: clojure

Clojure中的读者宏或核心功能是否类似于recur但可能具有非尾部位置?

例如,在这个递归函数中

(defn insertR* [newkey oldkey l]
  (cond
    (empty? l)  '()
    (not (seq? (first l)))
        (if (= (first l) oldkey)
        (cons oldkey (cons newkey (insertR* newkey oldkey (rest l))))
        (cons (first l) (insertR* newkey oldkey (rest l))))    
    :else
        (cons (insertR* newkey oldkey (first l)) (insertR* newkey oldkey (rest l)))))

我是否可以使用一些通用函数来调用自身而不是显式调用insertR*

2 个答案:

答案 0 :(得分:3)

你的问题不清楚。如果你的意思是:我可以不使用堆栈空间吗?不。你的insertR*有多个自我调用,没有堆栈就不可能表达。

如果你的意思是:我可以使用像recur这样的词来表示“递归呼唤你自己”,我不在乎它是否使用堆栈?并不是的。不过你可以自己写。类似的东西:

(defmacro defrec [name & fntail]
  `(def ~name (fn ~'recurse ~@fntail)))

(defrec foo [x]
  (when-not (zero? x)
    (recurse (dec x))))

我怀疑这有几个漏洞,但它基本上就是你所想的。

答案 1 :(得分:0)

为什么需要这种功能/宏? recur是为尾调用优化而创建的。看来你的功能不允许它(可能是我错了)。虽然你说你不需要它。为什么要将调用insertR *明确替换为其他内容? 如果你不喜欢每次传递newkey oldkey(并且它们没有改变),你可以创建内部函数,它将使用这个键。