Looks like I managed to answer the 'is it possible?' part of the question anyway -- something like this:
(defn range
[n]
(let [c (chan)]
(go
(loop [i 0]
(>! c i)
(if (< i n)
(recur (inc i))
(close! c))))
(fn [] (<!! c))))OTOH, you could use async's coroutine code (used to implement go blocks) to create generators, but because you have lazy sequences, that's not necessary either.
About lazy sequences: sometimes you want to avoid the allocation of lots of intermediate cons cells when mapping/filtering/etc. The reducers framework for example manages to avoid this sort of cost when the data structure supports something faster than first/rest recursion. I'm interested in extending reducers to work nicely over large files and other sequences which don't fit in memory, and some kind of iterable or generator-like abstraction could play a useful role in this.
(Actual coroutine-based generators might not be necessary, but would allow for a neat outward-facing API)