Laziness changes when work happens
Sequences process elements through intermediate operations on demand. A terminal operation, such as toList or sum, starts evaluation. This can avoid intermediate collections and skip work after an early limit.
fun main() {
var visited = 0
val result = (1..100).asSequence()
.map { visited++; it * 2 }
.filter { it > 10 }
.take(2)
.toList()
check(result == listOf(12, 14))
check(visited == 7)
}
The pipeline stops after finding two matches. Sorting, however, must generally consume the input before yielding sorted results; laziness does not make every operation streaming. Sequence wrappers and calls also have overhead, so they are not universally faster for small lists.
Avoid relying on side effects in sequence transformations. Re-consuming a sequence may repeat work, and some sequence sources allow only one traversal.
Exercise
Compare this pipeline with an eager list pipeline and count transformations. Then insert sortedDescending() before take and explain why early termination no longer avoids scanning the source.