It is with the rest of the code as given here, because it is filter
which does the wrapping in lazy-seq
. If step
called itself, it would do all the filtering at once instead of lazily.
(Updated.) If lazy-seq
was added to step
's body, step
could then call itself and still be lazy. This could be accomplished at least in these two ways:
by wrapping the entire body in lazy-seq
and replacing both the recursive call to filter
and the recur
with calls to step
; NB. in this case the step
function would need to be named (either by replacing the let
with letfn
, with the appropriate change in syntax, or by adding a name to the fn
form: (fn step ...)
); the lazy-seq
wrapping the outermost call to step
would then be unnecessary; also, at this point you could simply not have an inner helper function (just use this approach in filter
directly);
by leaving the lazy-seq
in filter
in place and wrapping the recursive call in step
(which would now be to step
itself) in lazy-seq
(with the recur
form remaining unchanged).
Note that clojure.core/filter
has a different implementation, with separate logic handling chunked sequences and no internal helper functions. In the non-chunked case it operates like the version of step
described in 1. above.