2017-09-27 2 views
0

私は関数を再帰的に使用できるようにラベルを使ってローカル関数を使用しようとしています。使用前にLispラベル関数が削除されました

(defun my-replace (e1 e2 L) 
    "Perform a deep replace e1 with e2 in L." 
    (labels ((my-replace-rec (e1 e2 L) 
      "Used for recursion" 
      (cond ((endp L) nil) 
        ((equal (car L) e1) (cons e2 (cdr L))) 
        ((listp (car L)) (my-replace-rec e1 e2 (car L))) 
        (t (my-replace-rec e1 e2 (cdr L))))))) 
    (my-replace-rec e1 e2 L)) 

私はスライムの機能を評価し、それを実行しようとする必要があり: これはコードです

; Note: Deleting unused function             
; (LABELS MY-REPLACE-REC)              
; ;                    

; Warning: This function is undefined:           
; MY-REPLACE-REC 

は、私は私ができるように、エラーメッセージをできるだけ多くで合わせてみましたが、I私はまだEmacs(これはまだ新しくなっています)を使って作業していて、小さなバッファからペーストしようとしています。

どうしてですか?それは定義され、使用されますが、使用される前に削除され続けているようです(おそらく、使用されていないためです)。

答えて

9

あなたはオフです。ちょうどletよう

(defun my-replace (e1 e2 L) 
    "Perform a deep replace e1 with e2 in L." 
    (labels ((my-replace-rec (e1 e2 L) 
       "Used for recursion" 
       (cond ((endp L) nil) 
        ((equal (car L) e1) (cons e2 (cdr L))) 
        ((listp (car L)) (my-replace-rec e1 e2 (car L))) 
        (t (my-replace-rec e1 e2 (cdr L)))))) 
      ;; empty labels body here.. 
     ) 
    ;; my-replace-rec is a global function expected to be defun-ed later 
    (my-replace-rec e1 e2 L)) 

labels仕事を:ここにあなたのコードが正しくidentedです。作成されたオブジェクトはlabelsの本体で使用する必要があり、関数が破棄された後には使用しないでください。 letで

(let ((a 10)) 
    ; a exists here 
) 
; a doesn't esist anymore 

あなたのコードで

(labels ((name (arg) arg)) 
    ; the fcuntion exists here 
) 
;the function doesn't esist anymore 

labelsで、あなたは何もしないとmy-replace-recが破壊された後、あなたはそれを呼び出すラベルの本体で、その後my-replace-recを作ります。 Common Lispは、後でそれをグローバルに定義することを期待しているため、警告はありません。使用しなかったスコープと比較しません。 my-replace-recへの呼び出しが正しくコードidentをしますlabels emacsの中で行われているように、終了括弧を移動させることにより

:あなたのコードを見たとき、あなたが持っているので

(defun my-replace (e1 e2 L) 
    "Perform a deep replace e1 with e2 in L." 
    (labels ((my-replace-rec (e1 e2 L) 
       "Used for recursion" 
       (cond ((endp L) nil) 
        ((equal (car L) e1) (cons e2 (cdr L))) 
        ((listp (car L)) (my-replace-rec e1 e2 (car L))) 
        (t (my-replace-rec e1 e2 (cdr L)))))) 
    (my-replace-rec e1 e2 L))) 

は、今では、この同じに見えますラベルにmy-replace-recが使用されているかのように識別され、エディタと実装ではラベルが使用されていないことが分かりました。

関連する問題