> 1: that the standard API requires that 
> every Sequence type can be instantiated so as to replicate the contents of 
> another? The whole value of Sequence to the examples is that it should be 
> impossible. 

No, it's the other way around. It should be possible to copy any (finite) 
Sequence into an Array, or any other type that declares it can be instantiated 
from a Sequence. The source of a Sequence could be anything, including data 
from external sources outside the program's control (like your /dev/random or 
wireless data examples).

> 2: that the standard API requires of every Sequence that it should serve the 
> expectation of the supposedly-uncoupled API of Array that it is free to 
> buffer the entire contents of any Sequence of the same Element? Need it or 
> not? Bad news for memory and performance.

I believe there's a default implementation on Sequence as well (which would 
return 0), so it functions more as an opt-in mechanism to help Array and 
similar buffering mechanisms estimate the size of the buffer they should 
allocate. (Remember that greedy `map` and friends all use Array, so they all 
use this kind of preallocation logic, too.)

> The answer may be that if the user knows enough to build a Sequence for which 
> laziness is indispensable, she should have better sense than to rely on those 
> two things, required or not.

Yes. Basically, the standard library doesn't model the difference between an 
infinite (or otherwise unwise-to-handle-non-lazily) sequence and a finite 
sequence. It expects you to know whether a particular sequence is going to be 
too large to handle greedily and refrain from doing so.

I consider this a weakness in the standard library and would prefer to see a 
more specific protocol hierarchy, perhaps along the lines of:

        /// Represents any series of elements which can be iterated over. 
Something which is 
        /// merely Iterable may not be finite and, in any case, is probably not 
wise to use in
        /// greedy algorithms. It also may not be possible to iterate over more 
than once.
        protocol Iterable {
                associatedtype Iterator: InteratorProtocol
                func makeIterator() -> Iterator
                
                associatedtype Subset: Iterable where Subset.Iterator.Element 
== Iterator.Element
        }
        extension Iterable {
                // only APIs which are either lazy or operate on the start of 
the series
        }
        
        /// Represents any finite series of elements which can be iterated 
over. Something which 
        /// is merely a Sequence may not be possible to iterate over more than 
once.
        protocol Sequence: Iterable {
                func underestimatedCount() -> Int
                associatedtype Subset: Sequence where Subset.Iterator.Element 
== Iterator.Element
        }
        extension Sequence {
                // adds greedy and tail-operating APIs, including `count`
        }
        
        /// Represents any finite, repeatable series of elements which can be 
iterated over and 
        /// looked up by index.
        protocol Collection: Sequence {
                associatedtype Index: ForwardIndex
                associatedtype Iterator = IndexingIterator<Self>
                
                var startIndex: Index { get }
                var endIndex: Index { get }
                subscript(position: Index) -> Iterator.Element { get }
                
                associatedtype Subset: Collection where Subset.Iterator.Element 
== Iterator.Element = Slice<Self>
                subscript(bounds: Range<Index>) -> Subset { get }
        }

The `for` loop would take an `Iterable` (since you can exit early from a `for` 
loop), but most APIs that are currently constrained to `Sequence` would not 
change to `Iterable`, unless they happened to operate lazily or only on the 
start of the series. That would keep you from accidentally passing an infinite, 
or might-as-well-be-infinite, sequence to a function that expected to be able 
to read the whole thing.

I might write a swift-evolution proposal to this effect someday, but right now 
the Collection protocols are being reworked and I doubt the relevant people 
have the bandwidth to work on Sequence too.

-- 
Brent Royal-Gordon
Architechies

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to