[swift-evolution] [Pitch] Remove destructive consumption from Sequence

Russ Bishop xenadu at gmail.com
Thu Jun 30 18:03:01 CDT 2016


> On Jun 30, 2016, at 3:37 PM, Dave Abrahams <dabrahams at apple.com> wrote:
> 
> 
>>>> I use it in a LazyRowSequence<T: SqlModelConvertible> where
>>>> querying Sqlite in WAL mode allows multiple concurrent readers to
>>>> get point-in-time snapshots of the database. The query can’t be
>>>> replayed without buffering all the rows in memory because Sqlite’s
>>>> step functions are not bi-directional. In some cases we are talking
>>>> about tens of thousands of rows (or even hundreds of thousands) and
>>>> the ability to avoid buffering them is a feature, not a bug.
>> 
>> IMHO the typical case for single-pass is IO. 
> 
> Yes.  Also, truly-random number generators.
> 
>> In this case it would work just as well as LazyRowIterator<T> assuming
>> the language allows for-in on an iterator.
> 
> So, you're not interested in using algorithms like map and filter on
> these things?
> 
> If it was just about for-in, we could say you can for-in over any
> instance of
> 
>   ()->T? 
> 

Fair point; we actually do take advantage of the lazy versions of filter and map. 

Does it make sense to say that single-pass sequences are always lazy?

               Iterable
          /                    \
	 /                       \
  LazyIterable      EagerIterable
       |                             |
 LazyCollection       Collection



LazyCollection is a wrapper around Collection so you can still use .lazy the way you would today.
LazyIterables are single-pass.
EagerIterables are multi-pass.



Maybe this doesn’t work because we’re talking about somewhat orthogonal things? I could imagine trying to model the idea of single vs multi pass and lazy vs eager separately:

> protocol Iterable {
>     associatedtype Iterator: IteratorProtocol
>     associatedtype Element = Iterator.Element
>     func makeIterator() -> Iterator
> }
> protocol MultiIterable: Iterable { }
> protocol SingleIterable: Iterable { }
> protocol LazyIterable: Iterable { }
> protocol EagerIterable: Iterable { }
> 
> extension MultiIterable where Self: EagerIterable {
>     func map<U>(t: @noescape (Element) -> U) -> [U] { }
> }
> 
> extension MultiIterable where Self: LazyIterable {
>     func map<U>(t: (Element) -> U) -> LazyMapMultiIterable<Self> { }
> }
> 
> extension SingleIterable where Self: LazyIterable {
>     func map<U>(t: (Element) -> U) -> LazyMapSingleIterable<Self> { }
> }


I guess it comes back to what you and others have pointed out - it might not be worth the effort to provide this level of flexibility.

Russ

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160630/7c0b44ea/attachment.html>


More information about the swift-evolution mailing list