<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 30, 2016, at 3:37 PM, Dave Abrahams &lt;<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>&gt; wrote:</div><div class=""><div class=""><br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">I use it in a LazyRowSequence&lt;T: SqlModelConvertible&gt; where<br class="">querying Sqlite in WAL mode allows multiple concurrent readers to<br class="">get point-in-time snapshots of the database. The query can’t be<br class="">replayed without buffering all the rows in memory because Sqlite’s<br class="">step functions are not bi-directional. In some cases we are talking<br class="">about tens of thousands of rows (or even hundreds of thousands) and<br class="">the ability to avoid buffering them is a feature, not a bug.<br class=""></blockquote></blockquote><br class="">IMHO the typical case for single-pass is IO. <br class=""></blockquote><br class="">Yes. &nbsp;Also, truly-random number generators.<br class=""><br class=""><blockquote type="cite" class="">In this case it would work just as well as LazyRowIterator&lt;T&gt; assuming<br class="">the language allows for-in on an iterator.<br class=""></blockquote><br class="">So, you're not interested in using algorithms like map and filter on<br class="">these things?<br class=""><br class="">If it was just about for-in, we could say you can for-in over any<br class="">instance of<br class=""><br class=""> &nbsp;&nbsp;()-&gt;T? <br class=""><br class=""></div></div></blockquote><br class=""></div><div>Fair point; we actually do take advantage of the lazy versions of filter and map.&nbsp;</div><div><br class=""></div><div>Does it make sense to say that single-pass sequences are always lazy?</div><div><br class=""></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Iterable</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&nbsp;/ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;\</div><div>&nbsp; LazyIterable &nbsp; &nbsp; &nbsp;EagerIterable</div><div>&nbsp; &nbsp; &nbsp; &nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div>&nbsp;LazyCollection &nbsp; &nbsp; &nbsp; Collection</div><div><br class=""></div><div><br class=""></div><div><br class=""></div><div>LazyCollection is a wrapper around Collection so you can still use .lazy the way you would today.</div><div>LazyIterables are single-pass.</div><div>EagerIterables are multi-pass.</div><div><br class=""></div><div><br class=""></div><div><br class=""></div><div>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:</div><div><br class=""></div><div><div></div><blockquote type="cite" class=""><div><font face="Menlo" class="">protocol Iterable {</font></div><div><font face="Menlo" class="">&nbsp; &nbsp; associatedtype Iterator: IteratorProtocol</font></div><div><font face="Menlo" class="">&nbsp; &nbsp; associatedtype Element = Iterator.Element</font></div><div><font face="Menlo" class="">&nbsp; &nbsp; func makeIterator() -&gt; Iterator</font></div><div><font face="Menlo" class="">}</font></div><div><font face="Menlo" class="">protocol MultiIterable: Iterable { }</font></div><div><font face="Menlo" class="">protocol SingleIterable: Iterable { }</font></div><div><font face="Menlo" class="">protocol LazyIterable: Iterable { }</font></div><div><font face="Menlo" class="">protocol EagerIterable: Iterable { }</font></div><div><font face="Menlo" class=""><br class=""></font></div><div><font face="Menlo" class="">extension MultiIterable where Self: EagerIterable {</font></div><div><font face="Menlo" class="">&nbsp; &nbsp; func map&lt;U&gt;(t: @noescape (Element) -&gt; U) -&gt; [U] { }</font></div><div><font face="Menlo" class="">}</font></div><div><font face="Menlo" class=""><br class=""></font></div><div><font face="Menlo" class="">extension MultiIterable where Self: LazyIterable {</font></div><div><font face="Menlo" class="">&nbsp; &nbsp; func map&lt;U&gt;(t: (Element) -&gt; U) -&gt; LazyMapMultiIterable&lt;Self&gt; { }</font></div><div><font face="Menlo" class="">}</font></div><div><font face="Menlo" class=""><br class=""></font></div><div><font face="Menlo" class="">extension SingleIterable where Self: LazyIterable {</font></div><div><font face="Menlo" class="">&nbsp; &nbsp; func map&lt;U&gt;(t: (Element) -&gt; U) -&gt; LazyMapSingleIterable&lt;Self&gt; { }</font></div><div><font face="Menlo" class="">}</font></div></blockquote></div><div><br class=""></div><div>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.</div><div><br class=""></div><div>Russ</div><br class=""></body></html>