迴圈作為表達

與今天使用的幾乎所有其他程式語言中的迴圈不同,Common Lisp 中的 LOOP 可以用作表示式:

(let ((doubled (loop for x from 1 to 10
                     collect (* 2 x))))
    doubled) ;; ==> (2 4 6 8 10 12 14 16 18 20)

(loop for x from 1 to 10 sum x)

MAXIMIZE 使 LOOP 返回已評估的最大值。MINIMIZEMAXIMIZE 相反。

(loop repeat 100
      for x = (random 1000)
      maximize x)

COUNT 告訴你在迴圈期間表示式計算到非 NIL 的次數:

(loop repeat 100
      for x = (random 1000)
      count (evenp x))

LOOP 還具有 someeverynotany 功能的等價物:

(loop for ch across "foobar"
     thereis (eq ch #\a))

(loop for x in '(a b c d e f 1)
    always (symbolp x))

(loop for x in '(1 3 5 7)
    never (evenp x))

…除了它們不限於迭代序列:

(loop for value = (read *standard-input* nil :eof)
   until (eq value :eof)
   never (stringp value))

LOOP 值生成動詞也可以用 -ing 字尾編寫:

(loop repeat 100
      for x = (random 1000)
      minimizing x)

也可以將這些動詞生成的值捕獲到變數(由 LOOP 巨集隱式建立)中,這樣你就可以一次生成多個值:

 (loop repeat 100
     for x = (random 1000)
     maximizing x into biggest
     minimizing x into smallest
     summing x into total
     collecting x into xs
     finally (return (values biggest smallest total xs)))

你可以擁有多個 collectcount 等子句,它們會收集到相同的輸出值。它們將按順序執行。

以下內容將關聯列表(可以與 assoc 一起使用)轉換為屬性列表(可以與 getf 一起使用):

(loop for (key . value) in assoc-list
      collect key
      collect value)

雖然這是更好的風格:

(loop for (key . value) in assoc-list
      append (list key value))