Lisp 循环 do let when

Lisp loop do let when

我正在尝试做这样的事情

(loop for i from 1 to 10
      do (let ((fi (funcall f i)))
           when (> fi 0)
           collect (list i fi)))

f 的计算成本很高,所以我只想计算一次。

这是行不通的,所以我在循环范围外引入了我的 fi 局部变量:

(let ((fi nil))
  (loop for i from 1 to 10
        do (setf fi (funcall f i))
        when (> fi 0)
        collect (list i fi)))

有没有一种完全包含在循环宏中的方法(如第一种方法)?

两个独立的 for 子句即可:

(loop for i from 1 to 10
      for fi = (funcall f i)
      when (> fi 0)
      collect (list i fi))

这两个迭代子句将在每次迭代时执行。第二个将看到 i.

的每个新值