2014-10-05 56 views
4

我注意到這個函數叫做rec在Common Lisp代碼中出現很多次,但我沒有找到它實際上在做什麼的引用。任何人都可以向我解釋它是什麼?例如,它會出現在一些代碼從另一個問題,How to convert a flat list into a nested tree-like structure?未標記的函數在帶標籤的Common Lisp源中稱爲rec?

(defun mimicry (source pattern) 
    (labels ((rec (pattern) 
      (mapcar (lambda (x) 
         (if (atom x) 
         (pop source) 
         (rec x))) 
        pattern))) 
    (rec pattern))) 
+1

請顯示更多背景。給整個程序使用它。 'rec'可能是本地的或特定於該程序的。 – 2014-10-05 19:38:25

+2

如果你看[這個例子](http://stackoverflow.com/a/24750461/1565698),你會看到'rec'被用作'labels'形式的本地函數名稱。如果你在任何地方將它改爲「香蕉」,它仍然可以工作,但是'rec'表示這是一個遞歸調用。在尾遞歸的情況下,有些使用名稱'loop',但它會使'loop'宏在相同範圍內不受影響,所以在Scheme中可能比CL更常見。 – Sylwester 2014-10-05 20:30:03

+0

@Sylwester我沒有添加太多的信息,認爲'rec'是lisp中使用的常用函數,但不知何故,只是不適合在線記錄。我用示例中的示例代碼更新了我的線程。你能告訴我這個'rec'函數是什麼,它究竟在做什麼? – dk123 2014-10-05 22:02:52

回答

8

rec是不是在你的代碼是全局函數,除非你這樣自己定義。這是一個用labels定義的本地輔助功能。

特殊運算符labels執行與defun類似的任務,除了綁定是本地的。這就像你使用defparameter來創建全局變量,而使用let來創建本地變量。

(labels ((banana (arg1) ; make function banana 
      (+ arg1 arg1))) 
    (banana 10))    ; use it 
; banana doesn't exist anymore 

是一樣的:

(defun banan (arg1) ; make function banana 
    (+ arg1 arg1)) 
(banana 10)   ; use it 
; banana still exists 

不同的是,香蕉停止對labels外,同時存在使用defun你侵擾你有輔助功能的全球環境。由於labels中的函數是本地函數,因此您可以使用常用名稱,如rec,loopaux作爲它們的名稱,它們不會污染代碼的其他部分。

還有一個類似的特殊運算符flet,其工作方式相同,但在本地環境中不包含其自己的函數,從而阻止您在自己的主體中調用您自己的函數。這些也是有用的,但你很少打電話給他們rec因爲rec意味着它的東西遞歸

這不是CL限制,而是編碼風格。我經常在Scheme編程中使用recloop這個名字,所以當我在CL中遇到它們時,我知道它們是什麼,但是在CL中,我從我的答案中看到,我在全局內部使用了auxtest-aux函數稱爲test

+0

謝謝你的回答,這清除了我的問題。 – dk123 2014-10-06 02:44:47