I learnt a lesson. This code does not work:
(let [matcher (re-matcher #"a" "a")]
(loop [result :ignore]
(if (not (.find matcher))
result
(recur (for [_ [:ignore]]
(.group matcher 0))))))
The loop calls .find before for has a chance to consume the match.Laziness and side-effects—an insidious combination!
that’s a neat little example
Is it necessary to use not here to have recur be in the tail position?
no both branches of the if are tail position
(loop [counter 4]
(if (zero? counter)
:done
(if (even? counter)
(recur (dec counter))
(recur (dec counter)))))
:done
here both branches of the if are in tail position and recur. The not there just puts the short exit first next to the clear condition. When the non-exit branch gets large it can sometimes get confusing what the simple little result way down at the bottom is for(if condition
;; 45 lines doing tons of work
(....)
;; here at the bottom, 45 lines away happens when `not condition`, but hard to remember to connect back to it
result
)