Common Lisp `loop`:最大化为 `let` 引入的局部变量

Common Lisp `loop`: maximize into local variable introduced by `let`

Common Lisp 中的 loop 工具允许多个值累加子句,maximize 等等。
现在,也可以将变量 var 赋给 maximize 子句:

(loop for x from 0 to 10 maximize (func x) into var)

我的问题是:

是否可以给 var 一个由 let 引入的新局部变量?

一个示例场景是:

(let ((var -1)) ; assume numeric result
  (loop for x from 0 to 10 maximize (func x) into var))

x有数值并不重要,只是为了说明目的。

混合绑定?

不,into 变量受 loop 约束。

您可以将 var 绑定到 loop 的 return 值:

(let ((var (loop for x from 0 to 10 maximize (func x))))
  ;; use var here
  ...)

复杂循环 - 使用多个值,函数式风格

如果你在一个循环中做很多事情,你可能想使用 values function in Common Lisp:

(multiple-value-bind (max min sum)
    (loop for x from 0 to 10
      maximize (f1 x) into max
      minimize (f2 x) into min
      sum (f3 x) into sum
      finally (return (values max min sum)))
  ;; use max, min and sum here
  ...)

请注意,multiple-value-bind and loop 绑定的变量 maxminsum 完全独立的,完全没有共同点 并且命名相同仅用于教学目的。

如果您重命名它们(为了代码的可读性,您绝对应该这样做!):

(multiple-value-bind (max min sum)
    (loop for x from 0 to 10
      maximize (f1 x) into max1
      minimize (f2 x) into min1
      sum (f3 x) into sum1
      finally (return (values max1 min1 sum1)))
  ;; use max, min and sum here
  ...)

然后重新编译你的代码,你会看到 disassembly 相同

复杂循环,使用finally,程序风格

正如@coredump 所建议的,您可以在 finally 构造中设置变量:

;; bind max, min and sum
(loop for x from 0 to 10
  maximize (f1 x) into max1
  minimize (f2 x) into min1
  sum (f3 x) into sum1
  finally (setq max max1
                min min1
                sum sum1))
;; use max, min, and sum; max1 et al do not exist here

总的来说,这里剥猫皮的方法不止一种...