Jacob K
02/08/2023, 9:12 AMSam
02/08/2023, 9:13 AMChannelIterator has suspending hasNext (but non-suspending next)Jacob K
02/08/2023, 9:16 AMSam
02/08/2023, 9:18 AMfor/in is based on operator function conventions, not interfaces. So anything which has operator fun next and operator fun hasNext is an iterator, and anything that has operator fun iterator is iterableSam
02/08/2023, 9:19 AMsuspendSam
02/08/2023, 9:19 AMJacob K
02/08/2023, 9:19 AMSam
02/08/2023, 9:20 AMFlow, thoughSam
02/08/2023, 9:20 AMJacob K
02/08/2023, 9:21 AMSam
02/08/2023, 9:21 AMJacob K
02/08/2023, 9:23 AMwhile (tree.hasNext()) {
val node = tree.next()
// do more supending stuff or break
}
Couldn't really figure out how that looks with flowsSam
02/08/2023, 9:28 AMflow {
while(tree.hasNext()) emit(tree.next())
}.takeWhile { node ->
// do more suspending stuff or return false
}.collect()Jacob K
02/08/2023, 9:30 AMSam
02/08/2023, 9:34 AMSam
02/08/2023, 9:37 AMJohann Pardanaud
02/08/2023, 9:38 AMJacob K
02/08/2023, 9:38 AMcollect() is slightly ugly though, since I'm not really collecting anything and I only want the "onEach" behavior.Jacob K
02/08/2023, 9:39 AMJohann Pardanaud
02/08/2023, 9:40 AMSequence and yield : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/-sequence-scope/yield.htmlJohann Pardanaud
02/08/2023, 9:41 AMCLOVIS
02/08/2023, 9:51 AMFlow is essentially the same as Sequence with a few bonus features (suspend, onCompletion /`onStart` /…)Jacob K
02/08/2023, 10:04 AMCLOVIS
02/08/2023, 10:05 AMsuspend in Sequence is not a "real" suspend . You need to use Flow from KotlinX.CoroutinesJacob K
02/08/2023, 10:10 AMCLOVIS
02/08/2023, 10:12 AMSequence is essentially a rewrite of Iterable , Flow is sequence + suspend , and you said you wanted an iterator with suspend .Jacob K
02/08/2023, 10:22 AMwalker.ancestors() returning an iterator-esque thing that can be used like an iterator typically would.
The above would only be used in suspending methods and the work to traverse the tree is also suspending.
One option seems to be to return anything that has a `suspend next()`and suspend hasNext() (no help from std lib to implement that - cmp. AbstractIterator with computeNext() )
The other option would be to have ancestors() return a "Flow of ancestors". To consume that I would need to use something like ancestors().takeWhile { // process or return null to stop traverseal }.collect()
(still not sure I understand if it was possible to emit items lazily, one at a time, in the flow example above)
I'm not sure what I want, but it's really interesting to learn the options. Whatever would be most idiomatic is probably preferable ;)CLOVIS
02/08/2023, 10:25 AM.map (once it's flattened, you can't transform it back into a tree using the stdlib). If you want to keep the structure, you'll have to create your own map etc implementation.