I suspect getting a single item out will be that you just make a
func next[T](i iterfunc[T]) T {
var item T
i(func(it T) bool){
item = it
return true // likely
})
return item
}
and use it. Semantics should be the same as ranging would desugar to (since that's all this is), though the variable arity will be slightly annoying of course.
Aah, yes, that's an excellent point. Thanks! That does complicate things a lot more.
Quite a lot more, as it essentially means you can only consume from iterators you create... which sorta defeats the purpose of iterators as a value, and degrades them almost completely to just a `range` helper.
>To convert one of these functions to a "next-based" or "pull-based" iterator, we plan to add a function to the standard library that runs the yield-based ("push-based") iterator in a coroutine, along the lines of the coro.Pull function in my recent blog post.
that's... an option I guess. Unless the runtime special-cases this coroutine though it seems like it'll probably have non-trivial performance cost, roughly equivalent to the channel + goroutine equivalents people sometimes build now. Which seems... not great. Bad enough that anyone even slightly performance-sensitive will probably avoid it.
(his coro post also mentions a proposed runtime change to improve the performance, but afaik previous attempts to get this kind of change into the language haven't worked out reliably, and you can't trust callers to be single-threaded)