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
@@ -92,21 +92,9 @@ static const char* libSource =
" }\n"
" }\n"
"\n"
" map(f) {\n"
" var result = new List\n"
" for (element in this) {\n"
" result.add(f.call(element))\n"
" }\n"
" return result\n"
" }\n"
" map(transformation) { new MapSequence(this, transformation) }\n"
"\n"
" where(f) {\n"
" var result = new List\n"
" for (element in this) {\n"
" if (f.call(element)) result.add(element)\n"
" }\n"
" return result\n"
" }\n"
" where(predicate) { new WhereSequence(this, predicate) }\n"
"\n"
" reduce(acc, f) {\n"
" for (element in this) {\n"
@@ -152,6 +140,32 @@ static const char* libSource =
" }\n"
"}\n"
"\n"
"class MapSequence is Sequence {\n"
" new(seq, f) {\n"
" _seq = seq\n"
" _f = f\n"
" }\n"
"\n"
" iterate(n) { _seq.iterate(n) }\n"
" iteratorValue(iterator) { _f.call(_seq.iteratorValue(iterator)) }\n"
"}\n"
"\n"
"class WhereSequence is Sequence {\n"
" new(seq, f) {\n"
" _seq = seq\n"
" _f = f\n"
" }\n"
"\n"
" iterate(n) {\n"
" while (n = _seq.iterate(n)) {\n"
" if (_f.call(_seq.iteratorValue(n))) break\n"
" }\n"
" return n\n"
" }\n"
"\n"
" iteratorValue(iterator) { _seq.iteratorValue(iterator) }\n"
"}\n"
"\n"
"class String is Sequence {\n"
" bytes { new StringByteSequence(this) }\n"
"}\n"