feat: replace eager map/where with lazy MapSequence and WhereSequence classes

Refactor Sequence.map and Sequence.where to return lazy MapSequence and WhereSequence wrappers instead of eagerly building a List. Add new MapSequence and WhereSequence classes that delegate iteration and apply the transformation or predicate on-the-fly. Update documentation to reflect lazy semantics and the need to call .list to materialize results. Adjust all existing tests to call .list on map/where results. Add new tests in test/core/sequence/ verifying lazy behavior with infinite Fibonacci iterators.
This commit is contained in:
Bob Nystrom
2015-04-01 14:22:02 +00:00
9 changed files with 160 additions and 44 deletions
+28 -14
View File
@@ -46,21 +46,9 @@ class Sequence {
}
}
map(f) {
var result = new List
for (element in this) {
result.add(f.call(element))
}
return result
}
map(transformation) { new MapSequence(this, transformation) }
where(f) {
var result = new List
for (element in this) {
if (f.call(element)) result.add(element)
}
return result
}
where(predicate) { new WhereSequence(this, predicate) }
reduce(acc, f) {
for (element in this) {
@@ -106,6 +94,32 @@ class Sequence {
}
}
class MapSequence is Sequence {
new(seq, f) {
_seq = seq
_f = f
}
iterate(n) { _seq.iterate(n) }
iteratorValue(iterator) { _f.call(_seq.iteratorValue(iterator)) }
}
class WhereSequence is Sequence {
new(seq, f) {
_seq = seq
_f = f
}
iterate(n) {
while (n = _seq.iterate(n)) {
if (_f.call(_seq.iteratorValue(n))) break
}
return n
}
iteratorValue(iterator) { _seq.iteratorValue(iterator) }
}
class String is Sequence {
bytes { new StringByteSequence(this) }
}