22

How can I achieve in a simple way a Lazy List in Kotlin? (For example, integers lazy list). I've been seeking official documentation, I've been googling for that without consistent results. Maybe the best tutorial I've found is here, but I wonder if there is a more Kotlin idiomatic way for doing that.

I've found the following on Kotlin's official blog, though I was unable to get an item, with integers[3] for example

var i = 0
integers = iterate{i++}

integers[3] // does not work
integers drop 3 // works
Mr.Q
  • 4,316
  • 3
  • 43
  • 40
loloof64
  • 5,252
  • 12
  • 41
  • 78
  • It seems that iterate is deprecated, but also I can get a stream thanks to the function streamOf(initialValue, closureForNext). As for the brackets operator, I can wrap my stream into a class and implements a get(index) method. As simple as this. I could "save" this question, according to me. – loloof64 Oct 26 '14 at 13:20
  • Possible duplicate of [Recursive definition of infinite sequence in Kotlin](http://stackoverflow.com/questions/35142548/recursive-definition-of-infinite-sequence-in-kotlin) – Vadzim Jul 29 '16 at 22:50
  • 3
    No. My question was asked before. – loloof64 Jul 30 '16 at 06:40

1 Answers1

20

As you correctly observed, sequenceOf (streamOf() in older versions) is the way to get a lazy stream of numbers. Unlike Haskell, there's no such thing as a lazy list in Kotlin's standard library, and for a good reason: the primary meaning of "list" in Haskell world and Java world is different. In Haskell, a list is primarily a linked list, a pair of head and tail, and the main operation is taking a head of such a list, which is straightforward to efficiently implement lazily. In Kotlin/Java, list is a data structure with random access to its elements, and the main operation is get(int), which can be implemented lazily, of course, but its performance will often be surprising for the user.

So, Kotlin uses streams for laziness, because they are good when it comes to the main use cases of lazy collections: iteration, filtering, mapping, and random access is unlikely to be encountered very often.

As you, again, correctly observe, drop lets you access elements by index, which makes the performance implications more explicit in the code.

BTW, what is your use case for lazy lists?

Bombe
  • 81,643
  • 20
  • 123
  • 127
Andrey Breslav
  • 24,795
  • 10
  • 66
  • 61
  • I am using lazy lists in order to process an higher order function, which computes fibonnaci numbers. So I can go further with this fibonacci sequence : sum of n even numbers for example. – loloof64 Oct 27 '14 at 09:32
  • 13
    Streams in Kotlin have been replaced with `Sequence` to avoid conflict with Java 8 streams. References to `streamOf` with `sequenceOf` or to convert another collection to sequence `asSequence` – Jayson Minard Dec 31 '15 at 00:43