Running this code eventually throws OOME :
`
(let [c (a/chan)]
(a/go (while (a/<! c)))
(a/go
(when-some [xs (range)]
(doseq [x xs]
(a/>! c x)))))
`
This one (with {{let}} instead of {{when-some}}) works fine :
`
(let [c (a/chan)]
(a/go (while (a/<! c)))
(a/go
(let [xs (range)]
(doseq [x xs]
(a/>! c x)))))
`
In the former, the range seq is stored on the heap (in go block's state array) and retained for the whole doseq iteration, althought it's not needed anymore after loop initialization.
In the latter, the range seq is stored on the stack so the compiler is able to perform its local clearing magic.
This behavior is likely to happen for every value spanning across multiple ssa blocks.