2017-07-29 18 views
0

我正在查看dotimes上的LispWorks Hyperspec,但我不明白第三個變量[result-form]正在做什麼。例子如下:解釋Lisp的點子:什麼是結果形式?

(dotimes (temp-one 10 temp-one)) => 10 
(setq temp-two 0) => 0 
(dotimes (temp-one 10 t) (incf temp-two)) => T 
temp-two => 10 

的Hyperspec說

...然後導致形式進行評估。在處理結果表單 時,var綁定到正文執行的次數。

不知道這是什麼意思。爲什麼這兩個dotimes示例中的第三個變量是必需的?我似乎能夠在第二個例子中完全拋棄它,並且它可以工作。我的下一個例子(不知道我在哪裏找到它),

(defun thing (n) 
    (let ((s 0)) 
     (dotimes (i n s) 
     (incf s i)))) 

拼圖我也是。 s服務有什麼用?

+1

結果窗體只是一個表單,它在循環完成後被評估爲產生返回值(或多個)。它是可選的(如果你不出來,返回值將是'NIL')。在你的最後一個例子中,變量'S'用於累計在循環結尾返回的'N'下的所有整數的和。 – jkiiski

回答

3

由於dotimes是一個宏觀的,看着它的宏擴展可以讓事情更清晰:


你的第一個例子,展開:

(pprint (MACROEXPAND-1 '(dotimes (temp-one 10 temp-one)))) 

我得到以下的輸出: (您可能因CL實施而異)

(BLOCK NIL 
    (LET ((#:G8255 10) (TEMP-ONE 0)) 
    (DECLARE (CCL::UNSETTABLE TEMP-ONE)) 
    (IF (CCL::INT>0-P #:G8255) 
     (TAGBODY 
     #:G8254 (LOCALLY (DECLARE (CCL::SETTABLE TEMP-ONE)) 
        (SETQ TEMP-ONE (1+ TEMP-ONE))) 
       (UNLESS (EQL TEMP-ONE #:G8255) (GO #:G8254)))) 
    TEMP-ONE)) 

有很多事情要做,但要看的關鍵是temp-one綁定到值0,並作爲表達式的值(以標準lisp評估順序)返回。


拿最後一個例子:

(pprint (macroexpand-1 '(dotimes (i n s) (incf s i)))) 

輸出:

(BLOCK NIL 
    (LET ((#:G8253 N) (I 0)) 
    (DECLARE (CCL::UNSETTABLE I)) 
    (IF (CCL::INT>0-P #:G8253) 
     (TAGBODY 
     #:G8252 (INCF S I) 
       (LOCALLY (DECLARE (CCL::SETTABLE I)) 
        (SETQ I (1+ I))) 
       (UNLESS (EQL I #:G8253) (GO #:G8252)))) 
    S)) 

正如你可以在這裏看到S的處理方式與溫度,一個在之前的例子一樣。


嘗試以下一項,而沒有經過最後一個變量:

(pprint (macroexpand-1 '(dotimes (i n) (do-something i)))) 

,你會得到:

(BLOCK NIL 
    (LET ((#:G8257 N) (I 0)) 
    (DECLARE (CCL::UNSETTABLE I)) 
    (IF (CCL::INT>0-P #:G8257) 
     (TAGBODY 
     #:G8256 (DO-SOMETHING I) 
       (LOCALLY (DECLARE (CCL::SETTABLE I)) 
        (SETQ I (1+ I))) 
       (UNLESS (EQL I #:G8257) (GO #:G8256)))) 
    NIL)) 

注意NIL是怎樣的返回值。