forked from Mirror/wren
Use deferred execution for Sequence.map and Sequence.where
The methods Sequence.map and Sequence.where are now implemented using deferred execution. They return an instance of a new Sequence-derived class that performs the operation while iterating. This has three main advantages: * It can be computationally cheaper when not the whole sequence is iterated. * It consumes less memory since it does not store the result in a newly allocated list. * They can work on infinite sequences. Some disadvantages are: * Iterating the returned iterator will be slightly slower due to the added indirection. * You should be aware that modifications made to the original sequence will affect the returned sequence. * If you need the result in a list, you now need to call Sequence.list on the result.
This commit is contained in:
@ -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]
|
||||
|
||||
@ -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,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]
|
||||
|
||||
@ -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
test/core/sequence/map.wren
Normal file
46
test/core/sequence/map.wren
Normal 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
test/core/sequence/where.wren
Normal file
40
test/core/sequence/where.wren
Normal 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
|
||||
Reference in New Issue
Block a user