Common Lisp `loop`: разверните локальную переменную, введенную`let`

loop средство в Common Lisp позволяет несколько пунктов накопления стоимости, 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 имеет числовое значение, это только для иллюстрации.

1 ответ

Решение

Смешать привязки?

Нет, into переменные связаны loop,

Что вы можете сделать, это связать свой var к возвращаемому значению loop:

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

Сложный цикл - использовать несколько значений, функциональный стиль

Если вы делаете много вещей в одном цикле, вы можете использовать функцию значений в 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
  ...)

Обратите внимание, что переменные max, min а также sum связаны multiple-value-bind а также loop являются совершенно отдельными и независимыми, и не имеют абсолютно ничего общего и называются одинаково только для дидактических целей.

Если вы переименуете их (как вы определенно должны сделать для удобства чтения кода!):

(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
  ...)

и перекомпилируйте ваш код, вы увидите, что разборка идентична.

Сложный цикл, использование 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

Вообще говоря, у кошки есть более одного способа...

Другие вопросы по тегам