on Thu Jun 30 2016, Russ Bishop <xenadu-AT-gmail.com> wrote: >> On Jun 30, 2016, at 3:37 PM, Dave Abrahams <dabrah...@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?
It might. Would it be inconvenient? > > Iterable > / \ > / \ > LazyIterable EagerIterable > | | > LazyCollection Collection > > LazyCollection is a wrapper around Collection so you can still use > .lazy the way you would today. Is it a protocol? Wrappers are usually generics. > > 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: The goal of generic programming is not to separate every idea into its own protocol. Discovering the natural dependency relationships and clusters of requirements and capabilities is a crucial part of it. As far as I can tell, lazy operations are always appropriate. > >> 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. -- Dave _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution