2011-05-17 135 views
4

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*明確?

回答

3

你的問題還不清楚。如果你的意思是:我可以做到這一點,而不使用堆棧空間?不可以。您的insertR*有多個自己的電話,這是不可能沒有堆棧表達。

如果你的意思是:我可以用一個像recur這樣的詞來表示「自己調用你自己」,我不關心它是否使用堆棧?不是真的。不過,你可以自己寫。像這樣:

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

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

我懷疑這有幾個漏洞,但它基本上是你在想什麼。

+0

突出顯示遞歸調用。我的意思是後者。 – 2011-05-17 17:40:36

0

爲什麼你需要這種功能/宏? recur被創建用於尾部呼叫優化。看來你的功能不允許它(可能是我錯了)。雖然你說你不需要它。你爲什麼要將你的調用insertR *明確地替換爲別的? 如果你不喜歡每次都傳遞newkey oldkey(並且它們沒有改變),你可以創建內部函數,它將使用這個鍵。

+0

就這樣,我可以在我的IDE上使用通用關鍵字 – 2011-05-17 17:44:59