2017-09-27 8 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 

나는 내가 할 수있는 등의 오류 메시지의 정도에 맞지하려고하지만 Emacs (저는 아직도 아주 새로워졌습니다)와 작은 버퍼를 붙여 넣으려고 노력하고 있습니다.

왜 이런 일이 발생합니까? 그것은 정의되고 사용되었지만 사용되기 전에 (사용되지 않았기 때문에) 계속 삭제 된 것 같습니다.

답변

9

신분 확인이 해제되었습니다. 여기에 코드가 올바르게 idented된다

(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 작품은 단지 let을 좋아한다. 함수가 소멸 된 후에가 아니라 labels 본문에 만들어진 개체를 사용해야합니다. 하자와

:

(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 이맥스에서 수행되도록 종료 괄호를 이동하여

: 당신은 당신의 코드를 볼 때이 있기 때문에

(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이 사용 된 것처럼 식별하고 편집기와 구현은 그렇지 않은 것으로 인식합니다.