<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 27, 2016, at 11:46 AM, Dave Abrahams <<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">on Mon Jun 27 2016, Matthew Johnson <</span><a href="http://matthew-at-anandabits.com/" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">matthew-AT-anandabits.com</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">> wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class="">On Jun 26, 2016, at 10:56 PM, Jonathan Hull via swift-evolution<br class=""><<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class="">Can’t a Sequence be potentially infinite, whereas a collection has a<br class="">defined count/endIndex? Other than that, I agree with your<br class=""></blockquote><br class=""><blockquote type="cite" class="">statement.<br class=""><br class="">Here is what I see as the appropriate structure:<br class=""><br class="">Iterator: Single destructive pass, potentially infinite, (should be for-in able)<br class="">Sequence: Guaranteed non-destructive multi-pass (vends Iterators),<br class="">potentially infinite, (should be subscript-able, gain most of<br class="">collection, but lose anything that relies on it ending)<br class="">Collection: Multi-pass, guaranteed finite, (no changes from current<br class="">form, except extra inits from Iterator/Sequence with end conditions)<br class=""><br class="">Right now we are allowed to have an infinite sequence, but calling<br class="">dropLast or non-lazy map will cause an infinite loop. These cases<br class="">could be made much safer by considering the potentially infinite and<br class="">finite cases separately…<br class=""></blockquote><br class="">I think this is pointing in the right general direction. It would<br class="">make working with `Sequence` much more straightforward and allow us to<br class="">depend on the multi-pass property that is true in practice of the most<br class="">common models of `Sequence`.<br class=""><br class="">But I agree that we should give much more careful consideration to<br class="">finite / infinite generally and for..in specifically.<br class=""><br class="">Now that I have been thinking about the finite / infinite distinction<br class="">more closely I have begun to notice a lot of code that is written<br class="">generically using `Sequence` where a for..in loop is really what is<br class="">required, however the “finite sequence” precondition is not explicitly<br class="">stated. Interestingly, this is the case with the standard library’s<br class="">eager `map` (but not the case with `dropLast` which explicitly notes<br class="">the precondition). I have been somewhat surprised to realize how<br class="">common this “bug” is (i.e. not stating a precondition). I think we<br class="">have gotten away with it thus far because the sequences most people<br class="">use most of the time in practice are finite. But that doesn’t mean we<br class="">should accept this as good enough - IMO it is way to easy to forget to<br class="">document this precondition (and obviously easier for users to overlook<br class="">than preconditions that are actually encoded in the type system,<br class="">violations of which are caught at compile time).<br class=""><br class="">The fact that this pattern is so pervasive is what I meant when I said<br class="">for..in “naturally” requires a finite sequence.<br class=""><br class="">IMO it’s better to encode preconditions in the type system when that<br class="">is practical, and especially when the precondition is shared by a vast<br class="">majority of code written using a particular construct (in this case a<br class="">for..in loop written using the most generic for..in-able protocol).<br class=""><br class="">I think the safest solution is to take the position that writing an<br class="">infinite loop is relatively uncommon and is a more “advanced”<br class="">technique, and thus should be done explicitly. Do people really write<br class="">infinite loops often enough that the convenience of using for..in when<br class="">writing infinite loops outweighs the safety benefit of preventing<br class="">accidental infinite loops? I haven’t seen a compelling argument for<br class="">this.<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Good questions. I'd also add: “do infinite sequences come up often</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">enough that accidentally looping on them forever is a problem?”</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div><div>That’s a good question as well. In practice the frequency of infinite sequences likely depends on the domain.</div><div><br class=""></div><div>IMO this falls into the same category as “do single pass sequences come up often enough that attempting to iterate over them twice is a problem. To paraphrase your previous post:</div><div><br class=""></div><div><blockquote type="cite" class="">Today, people see a beautiful, simple protocol (Sequence) to which many<br class="">things conform. They don't recognize that there's a semantic restriction<br class="">(<b class="">you can’t assume it is finite</b>!) on it, so they write libraries<br class="">of functions that may <b class="">iterate a Sequence to termination</b>. They test<br class="">their libraries with the most commonly-available Sequences, e.g. Arrays<br class="">and Ranges, which happen to be <b class="">finite</b>. Their tests pass! But their<br class="">constraints are wrong, their whole model of how to write generic code<br class="">over sequences is wrong, and some of their code is wrong.</blockquote><div></div><blockquote type="cite" class=""><div><br class=""></div>IMO this is a problematic programming model.</blockquote></div><div><br class=""></div><div>I definitely don’t mean to put words in your mouth here, but the logical structure of the argument appears identical to me regardless of which issue it is applied to. I am only trying to make that point.</div><br class=""><blockquote type="cite" class=""><div class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">If we adopt that position then for..in would need to be built on top<br class="">of a guaranteed finite construct. This would allow programmers to<br class="">continue writing generic code agains the most generic for..in-able<br class="">construct while eliminating a precondition that is often (usually?)<br class="">unstated and likely unconsidered.<br class=""><br class="">If we do decide to move forward with infinite for..in loops I think we<br class="">need to establish strong guidance around how to properly write generic<br class="">code with these protocols. Should such code really be constrained to<br class="">`Collection` rather than `Sequence` (i.e. should a potentially<br class="">infinite `Sequence` have an eager map)? If this is the guidance,<br class="">should it be paired with guidance that all finite sequences should<br class="">conform to `Collection`? Or is it sufficient to just educate<br class="">developers about this issue and expect people to document the “finite<br class="">Sequence” precondition when the constraint is `Sequence` rather than<br class="">`Collection`?<br class=""><br class="">I hope we will give serious consideration to these questions while<br class="">this topic is open for discussion.<br class=""><br class="">-Matthew<br class=""><br class=""><blockquote type="cite" class=""><br class="">Thanks,<br class="">Jon<br class=""><br class=""><blockquote type="cite" class="">on Wed Jun 22 2016, David Waite <<a href="http://david-at-alkaline-solutions.com" class="">david-AT-alkaline-solutions.com</a><br class=""><<a href="http://david-at-alkaline-solutions.com/" class="">http://david-at-alkaline-solutions.com/</a>>> wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">On Jun 22, 2016, at 2:57 PM, Dave Abrahams via swift-evolution<br class=""><swift-evolution at<span class="Apple-converted-space"> </span><a href="http://swift.org/" class="">swift.org</a><br class=""><<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a>>><br class="">wrote:<br class=""><br class=""><Ahem> “Iterators,” please.<br class=""></blockquote><br class="">That makes me happy - for some reason I thought it was still GeneratorProtocol<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">destructively, but such Generators would not conform to the needs of<br class="">Sequence. As such, the most significant impact would be the inability<br class="">to use such Generators in a for..in loop,<span class="Apple-converted-space"> </span><br class=""></blockquote><br class="">Trying to evaluate this statement, it's clear we're missing lots of<br class="">detail here:<br class=""><br class="">* Would you remove Sequence?<br class="">* If so, what Protocol would embody “for...in-able?”<br class=""></blockquote>No, I would just remove the allowance in the documentation and API<br class="">design for a destructive/consuming iteration. Sequence would be the<br class="">interface to getting access to repeatable iteration, without the need<br class="">for meeting the other requirements for Collection.<br class=""></blockquote><br class="">That would be wrong unless there exist substantial examples of a<br class="">multipass Sequence that *can't* meet the other requirements of<br class="">Collection without loss of efficiency. And since I can write an adaptor<br class="">that turns any multipass sequence into a Collection, I think it's<br class="">trivial to prove that no such examples exist.<br class=""><br class="">--<span class="Apple-converted-space"> </span><br class="">-Dave<br class=""></blockquote><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></blockquote><br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">--<span class="Apple-converted-space"> </span></span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">-Dave</span></div></blockquote></div><br class=""></body></html>