2010-03-08 12 views
10

我想知道是否有關於在Lisp中使用標籤的標準做法。我一直在用Lisp實現第一個答案中描述的算法Generating permutations lazily 我的當前版本使用標籤來分解部分功能。Lisp樣式問題標籤本地函數與否?

(defun next-permutation (pmute) 
    (declare (vector pmute)) 
    (let ((len (length pmute))) 
    (if (> len 2) 
     (labels ((get-pivot() 
        (do ((pivot (1- len) (1- pivot))) 
         ((or (= pivot 0) 
          (< (aref pmute (1- pivot)) 
           (aref pmute pivot))) 
         pivot))) 
       (get-swap (pivot) 
        (let ((swp (1- len))) 
        (loop for i from (1- len) downto pivot do 
          (if (or (and (> (aref pmute i) 
              (aref pmute (1- pivot))) 
             (< (aref pmute i) (aref pmute swp))) 
            (< (aref pmute swp) (aref pmute (1- pivot)))) 
           (setf swp i))) 
        swp)) 
       (next (swp pivot) 
        (rotatef (aref pmute (1- pivot)) (aref pmute swp)) 
        (reverse-vector pmute pivot (1- len)))) 
      (let ((piv (get-pivot))) 
      (if (> piv 0) 
       (next (get-swap piv) piv) 
       nil)))))) 

,因爲如果因爲這樣做在這種情況下,唯一的原因,這被認爲是不好的做法,有一次我在想,每個標籤僅稱的上是審美的原因。我會爭辯說,帶有標籤的當前版本更加清晰,但這可能違背了我不知道的常識,對Lisp來說是新手。

+1

如果你的函數不需要彼此引用(或者他們自己),你可以使用'flet'而不是'labels'。 – Svante 2010-03-08 21:37:54

+0

除了將這些額外的信息傳遞給其他讀取代碼的人之外,這樣做還有什麼好處嗎? – asm 2010-03-09 12:58:10

+0

可能不是。但是,請記住,您應該爲讀取代碼的下一個人編寫代碼,編譯器/解釋器不是您的主要受衆。 – Vatine 2010-03-09 14:18:41

回答

7

不,沒關係。編寫命名函數使得代碼更加自我記錄並且更加模塊化。

有時我還會列出函數arglist中使用的所有變量,而不是使用封閉函數中的變量。這使得界面更清晰一些,並有助於在代碼中移動功能(如有必要)。

本地函數還提供了添加本地文檔字符串和接口描述的可能性。

如果本地功能變得太大,它們也可能在外面使用,那麼我會提取它們並使它們成爲全局的。

1

除了Lisp新手之外我不會說任何其他的東西,我會說你做的是正確的事情:通過命名塊讓你的代碼更具可讀性。

2

我看不出有什麼不好。您正在使這兩個子進程非常清晰,並且很容易大塊,因此通過查看正文可以輕鬆快速掌握該函數的功能。如果您需要,現在也可以輕鬆地將內部功能推廣到全球功能。