В некотором смысле, разница между побочным эффектом или отсутствием побочного эффекта немного размыта.Возьмите следующую loop
версию (игнорируя, что loop
также имеет лучшие способы):
(loop :for x :in list
:for counter := (if (eq x 'a) (1+ counter) counter)
:finally (return counter))
Is counter
установить на каждом шаге или отскок?Т.е., изменена ли существующая переменная (как в setf
), или создана привязка новой переменной (как в рекурсии)?
Эта do
версия очень похожа на рекурсивную версию:
(do ((list args (rest list))
(counter 0 (+ counter (if (eq (first list) 'a) 1 0))))
((endp list) counter))
Тот же вопрос, что и выше.
Теперь «очевидная» loop
версия:
(loop :for x :in list
:count (eq x 'a))
Нет даже явной переменной длясчетчик.Есть ли побочные эффекты?
Внутренне, конечно, есть эффекты: создаются среды, устанавливаются привязки и, особенно, если есть оптимизация хвостового вызова, даже в рекурсивной версии, уничтожаемой / заменяемой на каждом шаге.
Я вижу как побочные эффекты только эффекты, которые влияют на вещи вне некоторой определенной области видимости.Конечно, все выглядит более элегантно, если вы также можете на уровне своего внутреннего определения избегать явного задания вещей и вместо этого использовать более декларативное выражение.