I've started work on a proposal that addresses the absence of lazy implementations of some Sequence
-related operations.
In it I propose conforming all existing lazily implemented Sequence
s to LazySequenceProtocol
:
Show / Hide
The following Sequence
s can't conform to LazySequenceProtocol
because they don't contain an underlying Sequence
and therefore can't conform to both Sequence
and LazySequenceProtocol
:
AnyBidirectionalCollection
AnyCollection
AnyIterator
AnyRandomAccessCollection
AnySequence
Array
ArraySlice
ClosedRange
CollectionOfOne
ContiguousArray
Dictionary
EmptyCollection
EmptyCollection.Iterator
KeyValuePairs
PartialRangeFrom
Range
Repeated
Set
StrideThrough
StrideTo
String
String.UnicodeScalarView
String.UTF16View
String.UTF8View
Substring
Substring.UnicodeScalarView
Substring.UTF16View
Substring.UTF8View
UnfoldSequence
Unicode.Scalar.UTF16View
UnsafeBufferPointer
UnsafeMutableBufferPointer
UnsafeMutableRawBufferPointer
UnsafeRawBufferPointer
UnsafeRawBufferPointer.Iterator
The following types can't conform to LazySequenceProtocol
because they aren't sufficiently lazy:
DropFirstSequence
DropWhileSequence
DropFirstSequence
can't conform to LazySequenceProtocol
because makeIterator()
pre-emptively drops the first k
elements due to performance reasons. For the latter type a lazy implementation already exists.
The following Sequence
s already conform to LazySequenceProtocol
and require no modifications:
LazyDropWhileSequence
LazyFilterSequence
LazyMapSequence
LazyPrefixWhileSequence
LazySequence
ReversedCollection
Slice
The following Sequence
s can conform to LazySequenceProtocol
:
LazyFilterSequence.Iterator
LazyPrefixWhileSequence.Iterator
LazyMapSequence.Iterator
The following Sequence
s can conform to LazySequenceProtocol
on the condition that Base
conforms to LazySequenceProtocol
:
EnumeratedSequence
EnumeratedSequence.Iterator
FlattenSequence
FlattenSequence.Iterator
IteratorSequence
JoinedSequence
PrefixSequence
ReversedCollection.Iterator
The conformance of FlattenSequence
to LazySequenceProtocol
means we can remove LazySequence
from the return
types of joined()
and flatMap(_:)
on LazySequenceProtocol
. The old implementations can be deprecated. It also requires the explicit declaration of FlattenCollection.SubSequence
.
The following Sequence
s can conform to LazySequenceProtocol
on the condition that Elements
conforms to LazySequenceProtocol
:
DefaultIndices
IndexingIterator
Finally, Zip2Sequence
can conform to LazySequenceProtocol
on the condition that Sequence1
and Sequence2
conform to LazySequenceProtocol
.
Then, for those inherited members from Sequence
that still don't contain a lazy implementation on LazySequenceProtocol
, overloads and types (conforming to LazySequenceProtocol
and conventionally prefixed with Lazy
) can be introduced:
-
dropFirst(_:)
(LazyDropFirstSequence
) -
dropLast(_:)
(LazyDropLastSequence
) -
reversed()
(LazyReversedSequence
) -
shuffled()
/shuffled(using:)
(LazyShuffledSequence
) -
sorted()
/sorted(by:)
(LazySortedSequence
) -
split(maxSplits:omittingEmptySubsequences:isSeparator:)
/split(separator:maxSplits:omittingEmptySubsequences:)
(LazySplitSequence
) -
suffix(_:)
(LazySuffixSequence
)
But before I do any further work I want to gauge if this is the right direction to take so I can determine the scope of the proposal.
For instance, I can imagine some backlash against a lazy implementation that on the first call to next()
requires the traversal of the entire underlying Sequence
plus additional memoisation, like reversed()
.
Is this the right approach in your opinion? And if not, where would you draw the line for inclusion?