2017-09-14 4 views
0

내가 (참고로 피터 세이 벨의 책을 사용) DO 매크로를 사용하는 함수를 작성했습니다 구속되지 않는 "DO"하지만 어떤 이유로, 내 함수를 컴파일 할 때 : 내가 얻을매크로 변수 - 정의

(defun test() 
    (do ((n 2 (1+ n)) 
     (m 1 (1+ m)) 
     (a (1+ n)) 
     (b (1+ m)) 
     (c (+ n m))) 
     ((= n 10) (* a b c)) 
     (print (* a b c)))) 

을 다음과 같은 경고 메시지가 :

WARNING: in TEST in lines 1..10 : N is neither declared nor bound, 
     it will be treated as if it were declared SPECIAL. 
WARNING: in TEST in lines 1..10 : M is neither declared nor bound, 
     it will be treated as if it were declared SPECIAL. 
WARNING: in TEST in lines 1..10 : N is neither declared nor bound, 
     it will be treated as if it were declared SPECIAL. 
WARNING: in TEST in lines 1..10 : M is neither declared nor bound, 
     it will be treated as if it were declared SPECIAL. 

나는 그것을 n 값이없는 것을 말한다 test을 실행하려고합니다.

바인딩 순서는 중요하지 않지만 어쨌든 재배치를 시도했지만 여전히 동일한 결과를 얻었습니다.

무엇이 여기에 있습니까?

내가 CLISP 2.49

+0

'DO'에 의해 생성 된 바인딩은 'DO'에서 init-forms에 보이지 않습니다. 대신에'DO * '를 원할 수도 있지만, 루프가 무엇을해야하는지 잘 모르겠습니다. 변수'A','B'' 및'C'는 계단식을 가지지 않으므로 값이 변하지 않습니다. 아마 당신은 init-forms가없는 것일까 요? – jkiiski

+0

@jkiiski 의견을 주셔서 감사합니다. 나는 그들이 init-form에서 사용할 수 없다는 것을 몰랐다. 계단 형태로 사용할 수 있기 때문에 생각했습니다. 모든 곳에서 사용할 수 있습니다./ 루프의 목적은 질문을 위해 본문을 제거하고 값을 반환합니다. 그것은 맥락에서 의미가 있습니다! 초기화 양식 제한을 해결하기 위해 내가하는 제안은 무엇입니까? – Gab

+0

DO 형식 대신에 DO 형식을 사용하면 작업 전에 모든 단계 형식을 평가해야하는 경우가 아니라면 (코드에 더 많은 변수가 표시되어 있지 않은 경우) . – jkiiski

답변

3

DO를 사용하고 어떤 변수 바인딩을 작성하기 전에 변수에 대한 모든 초기화-형태를 평가합니다. 즉, 바인딩은 동일한 DO의 init-forms에서 볼 수 없습니다.

코드는 출력이 A, BC은 변경하지 않을 때문에 매우 흥미로운 것은 아니지만, 대신 DO*를 사용하여 작동합니다.

(defun test() 
    (do* ((n 2 (1+ n)) 
     (m 1 (1+ m)) 
     (a (1+ n)) 
     (b (1+ m)) 
     (c (+ n m))) 
     ((= n 10) (* a b c)) 
    (print (* a b c)))) 

(test) 
; 18 
; 18 
; 18 
; 18 
; 18 
; 18 
; 18 
;=> 18 

DO* 그렇지 않으면 DO과 동일하지만, 평가하고 바인딩 하나 하나를 설정, 그래서 당신은 초기화-형태로 이전의 변수를 참조 할 수 있습니다. 스텝 폼을 사용하여 변수를 업데이트 할 때도 마찬가지입니다.