Это с остальной частью кода, как указано здесь, потому что это filter
, который делает обертку в lazy-seq
. Если бы step
называл себя, он бы делал всю фильтрацию сразу, а не лениво.
(Обновлено). Если lazy-seq
был добавлен в step
«s тела, step
мог бы назвать себя и по-прежнему быть ленивым. Это может быть достигнуто, по крайней мере в этих двух направлениях:
путем обертывания всего тела в lazy-seq
и замена как рекурсивный вызов filter
и recur
с вызовами step
; NB. в этом случае необходимо будет назвать функцию step
(либо путем замены let
на letfn
с соответствующим изменением синтаксиса, либо путем добавления имени в форму fn
: (fn step ...)
); тогда lazy-seq
обертывание внешнего вызова на step
было бы ненужным; также, на данный момент вы можете просто не иметь внутренней вспомогательной функции (просто используйте этот подход в filter
);
, оставляя lazy-seq
в filter
на месте и оберточной рекурсивный вызов в step
(который теперь будет самые step
) в lazy-seq
(с recur
формы остается неизменной).
Обратите внимание, что clojure.core/filter
имеет другую реализацию, с раздельной обработкой логики фрагментированной последовательности и никаких внутренних вспомогательными функций. В не-chunked случае он работает как версия step
, описанная в 1. выше.
Но если я обернуваю все тело 'lazy-seq', то' recur' не будет находиться в хвостовой позиции – tempestadept
@tempestadept. Право, вам придется заменить его на другой рекурсивный вызов. ('clojure.core/filter' эффективно работает так, как в случае с неядерным.) Я отредактировал ответ, чтобы принять это во внимание. –