2009-09-06 64 views
7

我是lisp的新手,並且正在編寫幾個簡單程序以便更熟悉它。我正在做的事情之一是編寫一個階乘方法的遞歸和迭代版本。但是,我遇到了一個問題,似乎無法解決它。Lisp警告:xx既沒有聲明也沒有綁定,它將被視爲聲明爲特殊

我看到類似的錯誤 Lisp: CHAR is neither declared nor bound 但實際上沒有達到解決方案,除了OP意識到他犯了一個「輸入錯誤」。在REPL中,我可以使用setf函數,它工作正常。我也用emacs來使用LispBox。我將不勝感激任何建議!

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

警告在IT-FACT: 結果既不申報也沒有約束, 就好像宣佈SPECIAL它將被處理。

+1

見http://www.cs.cmu.edu/Groups/AI /html/faqs/lang/lisp/part1/fa​​q-doc-4.html,特別是「GOOD:」示例。這裏的人都非常友好,但是如果代碼縮進更像典型的Lisp代碼,則代碼更容易閱讀。乾杯! – Alec 2009-09-06 17:05:44

回答

5

您需要綁定變量「結果」 - 用「讓」,例如 - 在開始使用前:

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

對於您可能需要閱讀this進一步瞭解詳情......

+0

哦,我明白了。我之前也嘗試過「讓」,但我使用它,就好像它是setf一樣,並且我沒有在let的括號內包含dotimes循環。我想這與範圍或某事有關。感謝大家的幫助! – Aaron 2009-09-06 16:38:41

+0

Seriousy,正確縮進你的代碼。 – 2009-09-08 13:27:25

+0

因爲我主要是一名java程序員,所以您可以很容易地看到爲什麼我放棄了括號(只是將它們視爲括號而已)。由於這裏提供的例子,我已經習慣於把關閉的父母放在一條線上,所以它「嚴重」並不是什麼大問題。謝謝你:) – Aaron 2009-09-25 02:22:21

5

在Lisp中,局部變量必須用LET或其他創建局部變量的形式顯式聲明。 與例如Python或JavaScript,其中賦值給變量在當前詞法範圍中創建變量。

你的例子可以寫成這樣:

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

閒談評論:有是把右括號放在單獨的行毫無意義。

6

有幾件事情是不是錯了好Lisp的風格:

(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 2009-09-06 16:43:57