feat: replace eager list-based map/where with deferred MapSequence and WhereSequence classes

Introduce MapSequence and WhereSequence subclasses of Sequence that apply transformations lazily during iteration instead of building intermediate lists. Update Sequence.map and Sequence.where to return these deferred wrappers, modify all existing tests to call .list on results, and add new infinite-sequence tests verifying lazy behavior on Fibonacci iterators.
This commit is contained in:
Thorbjørn Lindeijer
2015-03-28 21:51:50 +00:00
parent adc64d65b9
commit 5b71ac0c56
9 changed files with 160 additions and 44 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
var a = [1, 2, 3]
var b = a.map {|x| x + 1 }
var b = a.map {|x| x + 1 }.list
IO.print(b) // expect: [2, 3, 4]
+2 -2
View File
@@ -1,6 +1,6 @@
var a = [1, 2, 3]
var b = a.where {|x| x > 1 }
var b = a.where {|x| x > 1 }.list
IO.print(b) // expect: [2, 3]
var c = a.where {|x| x > 10 }
var c = a.where {|x| x > 10 }.list
IO.print(c) // expect: []
+1 -1
View File
@@ -1,3 +1,3 @@
var a = 1..3
var b = a.map {|x| x + 1 }
var b = a.map {|x| x + 1 }.list
IO.print(b) // expect: [2, 3, 4]
+2 -2
View File
@@ -1,6 +1,6 @@
var a = 1..3
var b = a.where {|x| x > 1 }
var b = a.where {|x| x > 1 }.list
IO.print(b) // expect: [2, 3]
var c = a.where {|x| x > 10 }
var c = a.where {|x| x > 10 }.list
IO.print(c) // expect: []
+46
View File
@@ -0,0 +1,46 @@
// Infinite iterator demonstrating that Sequence.map is not eager
class FibIterator {
new {
_current = 0
_next = 1
}
iterate {
var sum = _current + _next
_current = _next
_next = sum
}
value { _current }
}
class Fib is Sequence {
iterate(iterator) {
if (iterator == null) return new FibIterator
iterator.iterate
return iterator
}
iteratorValue(iterator) { iterator.value }
}
var squareFib = (new Fib).map {|fib| fib * fib }
var iterator = null
IO.print(squareFib is Sequence) // expect: true
IO.print(squareFib) // expect: instance of MapSequence
iterator = squareFib.iterate(iterator)
IO.print(squareFib.iteratorValue(iterator)) // expect: 0
iterator = squareFib.iterate(iterator)
IO.print(squareFib.iteratorValue(iterator)) // expect: 1
iterator = squareFib.iterate(iterator)
IO.print(squareFib.iteratorValue(iterator)) // expect: 1
iterator = squareFib.iterate(iterator)
IO.print(squareFib.iteratorValue(iterator)) // expect: 4
iterator = squareFib.iterate(iterator)
IO.print(squareFib.iteratorValue(iterator)) // expect: 9
+40
View File
@@ -0,0 +1,40 @@
// Infinite iterator demonstrating that Sequence.where is not eager
class FibIterator {
new {
_current = 0
_next = 1
}
iterate {
var sum = _current + _next
_current = _next
_next = sum
}
value { _current }
}
class Fib is Sequence {
iterate(iterator) {
if (iterator == null) return new FibIterator
iterator.iterate
return iterator
}
iteratorValue(iterator) { iterator.value }
}
var largeFibs = (new Fib).where {|fib| fib > 100 }
var iterator = null
IO.print(largeFibs is Sequence) // expect: true
IO.print(largeFibs) // expect: instance of WhereSequence
iterator = largeFibs.iterate(iterator)
IO.print(largeFibs.iteratorValue(iterator)) // expect: 144
iterator = largeFibs.iterate(iterator)
IO.print(largeFibs.iteratorValue(iterator)) // expect: 233
iterator = largeFibs.iterate(iterator)
IO.print(largeFibs.iteratorValue(iterator)) // expect: 377