[stdlib] Is there a lazy List type in the standard lib?


#1

Hi :

I’d like to see something like scala.collection.immutable.Stream (http://www.scala-lang.org/api/current/scala/collection/immutable/Stream.html)
so that functions like Collection.filter doesn’t have to return a List with all data loaded immediately.

So in general I was wondering is there any new collection types planned for the stdlib?

Scala seems to have a good collection lib, although they are a bit complicated.


#2

Hi!

Iterators in Kotlin are lazy (they work a lot like views in Scala collections).

Instead of executing immediately, functions such as map, filter and takeWhile return a new Iterator instance that lazily computes values.

See https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/Iterators.kt to see the supported functions and how they are implemented via classes such as MapIterator and FilterIterator.

Cheers,
Andrew


#3

Thanks for the information :)

I misunderstood the names and thought the Iterators were same as java iterators.

So functions like filter and map return a List<T>, which is actually an AbstractIterator implementation


#4

zhaopuming wrote:

So functions like filter and map return a List<T>, which is actually an AbstractIterator implementation


Not quite, they’re extension functions that return an Iterator<T>. e.g. for filter the function is:

public inline fun <T> java.util.Iterator<T>.filter(predicate: (T) -> Boolean) : java.util.Iterator<T> = FilterIterator<T>(this, predicate)

They do all seem to extend AbstractIterator, but that’s really just a private implementation detail.

The important thing is that they are lazy and can be chained together. There’s an example in the tests that demonstrates how they can be used on an infinite fibonacci sequence:

fibonacci().filter { it > 100 }.takeWhile { it < 1000 }

See: http://jetbrains.github.com/kotlin/versions/snapshot/apidocs/kotlin/java/util/Iterator-extensions.html#filter(jet.Function1)

Cheers,
Andrew


#5

Currently the standard library is using the convention that Iterables/Collections are all eager (non-lazy) and Iterator is the way of working lazily.

The sample API is available on both collections and iterators and you can switch from collection/eager to iterator/lazy at any point via (iterator() or toList()); so you have fine grained control over lazy or eagerness in a simple compositional API.