2017-09-14 88 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. 

當我嘗試執行test,它說,n沒有價值。

我覺得綁定順序並不重要,但我試着重新整理它,仍然收到相同的結果。

缺少什麼我在這裏?

我使用CLISP 2.49

+0

由'DO'創建的綁定對那個'DO'中的init表單不可見。你可能需要'DO *',但我不確定循環應該做什麼。變量'A','B'和'C'沒有步驟形式,所以它們的值不會改變。也許你錯過了那些初始形式? – jkiiski

+0

@jkiiski感謝您的評論。我不知道它們不是以初始形式提供的。我想,因爲我可以在步驟形式中使用它們,所以無處不在:/ 至於循環的目的,爲了解決問題,我刪除了主體並返回了值。它在上下文中是有意義的!你會建議我如何解決初始表單限制? – Gab

+0

使用'DO *'而不是'DO'應該可以工作,除非您需要在任何賦值之前對所有步驟進行評估(似乎並非如此,除非您有更多變量未在代碼中顯示) 。 – jkiiski

回答

3

DO評估所有的init-形式的變量創建任何變量綁定之前。這意味着綁定對同一個DO中的初始表單不可見。

的代碼應該工作使用DO*代替,雖然產量不是很有趣,因爲ABC永遠不會改變。

(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,但它評估,並建立綁定一個接一個,所以你可以參考前面的兩個變量在init-形式。使用步驟更新變量時也完成了相同的操作。