2009-09-06 4 views
7

저는 Lisp에 익숙하지 않고 좀 더 익숙해지기 위해 몇 가지 간단한 프로그램을 작성 중입니다. 내가하고있는 일 중 하나는 계승 방법의 재귀적이고 반복적 인 버전을 작성하는 것입니다. 그러나, 나는 문제를 가로 질러 왔고 그것을 해결하는 것처럼 보일 수 없다. Lisp 경고 : xx는 선언도 바인딩도되어 있지 않습니다. 선언 된 것처럼 취급됩니다. SPECIAL

나는 Lisp: CHAR is neither declared nor bound 에서 비슷한 오류를보고하지만 영업 이익은 그가 "타이핑 실수"를 만들어 실현보다 용액은 실제로 다른 도달하지 않았다. REPL에서는 setf 함수를 사용할 수 있습니다. 나는 또한 이맥스와 함께 LispBox를 사용하고있다. 나는 어떤 제안을 주셔서 감사합니다! IT-사실

(defun it-fact(num) 
    (setf result 1) 
    (dotimes (i num) 
    (setf result (* result (+ i 1))) 
) 
) 

경고 :이 특별 선언 된 것처럼 결과가 선언되지도 구속되지도, 은이 처리됩니다.

+1

참조 http://www.cs.cmu.edu/Groups/AI /html/faqs/lang/lisp/part1/faq-doc-4.html, 특히 "좋은 :"예. 여기에있는 사람들은 꽤 친절합니다. 그러나 전형적인 Lisp 코드처럼 더 들여 쓰기하면 코드를 읽기가 더 쉽습니다. 건배! – Alec

답변

5

당신은 변수 '결과'를 바인드해야 - 예를 들어, '하자'를 사용 - 그것을 사용하기 시작하기 전에 : 당신이 this을 읽어보십시오 학습과 자세한 내용은

(defun it-fact(num) 
    (let ((result 1)) 
    (dotimes (i num) 
     (setf result (* result (+ i 1)))))) 

을 ...

+0

아, 알겠습니다. 전에 'let'을 시도해 봤지만 setf 인 것처럼 사용했다. 그리고 let의 괄호 안에 점선으로 된 루프를 포함하지 않았다. 나는 그것이 범위 또는 무언가와 관련이 있다고 생각합니다. 모두 도움을 주셔서 감사합니다! – Aaron

+0

심각하게 코드를 들여 쓰기하십시오. –

+0

저는 주로 자바 프로그래머이므로 괄호를 사용하지 않은 이유를 쉽게 볼 수 있습니다 (대괄호 이외의 것으로보기). 그 이후 나는 여기에 제시된 예제 덕택에 닫는 parenths를 한 줄에 넣는 데 익숙해 졌으므로 "심각하게"큰 거래는 아닙니다. 어쨌든 고마워요 :) – Aaron

5

Lisp에서 로컬 변수는 LET 또는 로컬 변수를 만드는 다른 형식으로 명시 적으로 선언해야합니다. 과 다릅니다. Python 또는 JavaScript 변수에 대한 할당은 현재 어휘 범위에서 변수를 만듭니다.

귀하의 예는 다음과 같이 쓸 수있다 :

(defun it-fact(num) 
    (let ((result 1)) 
    (dotimes (i num) 
     (setf result (* result (+ i 1)))))) 

에서 벗어난 주제 주석 : 별도의 라인에 닫는 괄호를 넣어 아무 문제가 없다.

6

몇 가지가 리스프 스타일 너무 좋아 잘못된 여부가 있습니다

(defun it-fact(num)      ; style: use a space before (
    (setf result 1)      ; bad: variable result is not introduced 
    (dotimes (i num) 
    (setf result (* result (+ i 1)))  ; bad: extra addition in each iteration 
)          ; style: parentheses on a single line 
)          ; bad: no useful return value 

가능한 버전 :

(defun it-fact (num) 
    (let ((result 1))      ; local variable introduced with LET 
    (loop for i from 1 upto num   ; i starts with 1, no extra addition 
     do (setf result (* result i))) 
    result))        ; result gets returned from the LET 
+2

제안 해 주셔서 감사합니다! 그래, 점 dotimes 0에서 시작하고 곱셈에서 늘리지 않았다면 항상 0을 반환합니다 깨달 았어 ... 귀하의 루프가 읽기 쉽게 보이네요. 나는 C++/java에서 중괄호로 사용 되었기 때문에 모든 줄에 괄호를 넣었다고 생각하지만, lisp에 대한 연습을 채택하려고합니다. 죄송합니다. 예, 반환을 간과 했으므로 이러한 사항을 지적 해 주셔서 감사합니다. – Aaron