Hello and welcome!
It’s true that Clojure expects
recur calls in tail positions, but an accumulator is not strictly necessary.
Just as @mvarela wrote, you are free to use
recur without any arguments at all.
The implementation of
while is a good example. It’s useful if the condition of your loop depends on some external side-effects.
In Clojure we tend to use an explicit accumulator because our data structures are immutable. The same applies to other languages based on immutable data structures, such as Erlang or Haskell.
When we accumulate results of recursion, we don’t modify a mutable accumulator. Instead, we create a new one, derived from the existing one. The implementation of Clojure’s persistent data structures makes it less expensive than it sounds.
If our data were mutable, we could modify them in place instead of carrying over an explicit accumulator. Parts of Clojure’s standard library are implemented that way using transients. It’s not something we resort to often outside of hotspots of our applications.