<div dir="ltr">On Sun, Oct 15, 2017 at 12:33 AM, Jonathan Hull <span dir="ltr">&lt;<a href="mailto:jhull@gbis.com" target="_blank">jhull@gbis.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On Oct 14, 2017, at 9:59 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="m_490495919921887324Apple-interchange-newline"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">On Sat, Oct 14, 2017 at 11:48 PM, Jonathan Hull<span class="m_490495919921887324Apple-converted-space"> </span><span dir="ltr">&lt;<a href="mailto:jhull@gbis.com" target="_blank">jhull@gbis.com</a>&gt;</span><span class="m_490495919921887324Apple-converted-space"> </span>wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><br><div><span><blockquote type="cite"><div>On Oct 14, 2017, at 9:21 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:</div><br class="m_490495919921887324m_-4349070227452406246m_-6190350261235986415Apple-interchange-newline"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">On Sat, Oct 14, 2017 at 10:55 PM, Jonathan Hull<span class="m_490495919921887324m_-4349070227452406246m_-6190350261235986415Apple-converted-space"> </span><span dir="ltr">&lt;<a href="mailto:jhull@gbis.com" target="_blank">jhull@gbis.com</a>&gt;</span><span class="m_490495919921887324m_-4349070227452406246m_-6190350261235986415Apple-converted-space"> </span>wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><br><div><span><blockquote type="cite"><div>On Oct 14, 2017, at 7:55 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_490495919921887324m_-4349070227452406246m_-6190350261235986415m_-208421619427395776Apple-interchange-newline"><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">&gt; Ordered, yes, but it’s only admittedly poor wording that suggests multi-pass, and I don’t think anything there suggests finite.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">If a Sequence is &quot;guaranteed to iterate the same every time,&quot; then surely it must be multi-pass; what&#39;s the alternative?<br></div></div></blockquote><div><br></div></span><div>Single-pass, but where two dictionaries/sets with the same elements would be guaranteed to output the same ordering.</div></div></div></blockquote><div><br></div><div>I&#39;m not sure I understand. A single-pass sequence is one where iteration can happen only once because it is destructive. By definition, then, it is not guaranteed to &quot;iterate the same&quot; a second time. Neither sets nor dictionaries are single-pass sequences. Kevin says that his definition of a &quot;Sequence&quot; is something &quot;guaranteed to iterate the same every time,&quot; which requires them to be multi-pass, does it not?<br></div></div></div></div></div></blockquote><div><br></div></span><div>But if I am comparing two single-pass things, the order can still be defined when they compare that one time.  Single-pass doesn’t mean that the order is undefined.  On the contrary, as you point out, it has a “first” thing, and then a thing after that, and so on.</div><div><br></div><div>Regardless, most of the objects we are talking about here are multi-pass collections (e.g. sets).</div></div></div></blockquote><div><br></div><div>Right, but I&#39;m trying to figure out why Kevin wants a Sequence to &quot;iterate the same every time&quot; and in what way that&#39;s not simply a Collection.<br></div></div></div></div></div></blockquote><div><br></div></span><div>I guess you will have to ask Kevin that.</div></div></div></blockquote><div><br></div><div>Indeed, I&#39;m asking Kevin that. </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span class=""><div></div><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><span><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><div> That ordering can be arbitrary, but it shouldn’t leak internal representation such that the method used to create identical things affects the outcome of generic methods because of differences in internal representation.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><span><div><br></div><br><blockquote type="cite"><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"> It would be better to say that the iteration order is well-defined. That will almost always mean documented, and usually predictable though obviously e.g. RNGs and iterating in random order will not be predictable by design.</div><blockquote class="gmail_quote" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div dir="auto"><div><span class="m_490495919921887324m_-4349070227452406246m_-6190350261235986415m_-208421619427395776gmail-"><br><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><div>That&#39;s actually more semantically constrained than what Swift calls a `Collection` (which requires conforming types to be multi-pass and(?) finite). By contrast, Swift&#39;s `SpongeBob` protocol explicitly permits conforming single-pass, infinite, and/or unordered types.<span class="m_490495919921887324m_-4349070227452406246m_-6190350261235986415m_-208421619427395776Apple-converted-space"> </span></div></div></div></div></blockquote><div><br></div></span>I think you’re talking about Sequence here, I’ve lost track of your nonsense by now. Yes, the current Swift protocol named Sequence allows unordered types. You seem to keep asserting that but not actually addressing my argument, which is <b>that allowing Sequences to be unordered with the current API is undesired and actively harmful, and should</b> <b>therefore</b><b> be changed</b>.</div></div></div></blockquote><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">What is harmful about it?</div></blockquote></span></div><br><div>After thinking about it, I think the harmful bit is that unordered sequences are leaking internal representation (In your example, this is causing people to be surprised when two sets with identical elements are generating different sequences/orderings based on how they were created).  You are correct when you say that this problem is even true for for-in.</div></div></blockquote><div><br></div><div>I would not say it is a problem. Rather, by definition, iteration involves retrieving one element after another; if you&#39;re allowed to do that with Set, then the elements of a Set are observably ordered in some way. Since it&#39;s not an OrderedSet--i.e., order doesn&#39;t matter--then the only sensible conclusion is that the order of elements obtained in a for...in loop must be arbitrary. If you think this is harmful, then you must believe that one should be prohibited from iterating over an instance of Set. Otherwise, Set is inescapably a Sequence by the Swift definition of Sequence. All extension methods on Sequence like drop(while:) are really just conveniences for common things that you can do with iterated access; to my mind, they&#39;re essentially just alternative ways of spelling various for...in loops.</div></div></div></div></div></blockquote><br></span></div><div>I think an argument could be made that you shouldn’t be able to iterate over a set without first defining an ordering on it (even if that ordering is somewhat arbitrary).  Maybe we have something like a “Sequenc(e)able” protocol which defines things which can be turned into a sequence when combined with some sort of ordering.  One possible ordering could be the internal representation (At least in that case we are calling it out specifically).  If I had to say “setA.arbitraryOrder.elementsE<wbr>qual(setB.arbitraryOrder)” I would definitely be less surprised when it returns false even though setA == setB.</div></div></blockquote><div><br></div><div>Well, that&#39;s a totally different direction, then; you&#39;re arguing that `Set` and `Dictionary` should not conform to `Sequence` altogether. That&#39;s fine (it&#39;s also a direction that some of us explored off-list a while ago), but at this point in Swift&#39;s evolution, realistically, it&#39;s not within the realm of possible changes.<br></div></div></div></div></blockquote><div><br></div></span><div>I am actually suggesting something slightly different.  Basically, Set and Dictionary’s conformance to Collection would have a different implementation.  They would conform to another protocol declaring that they are unordered. That protocol would fill in part of the conformance to sequence/collection using a default ordering, which is mostly arbitrary, but guaranteed to produce the same ordering for the same list of elements (even across collection types).  This would be safer, but a tiny bit slower than what we have now (We could also potentially develop a way for collections like set to amortize the cost). For those who need to recover speed, the new protocol would also define a property which quickly returns a sequence/iterator using the internal ordering (I arbitrarily called it .arbitraryOrder).</div><div><br></div><div>I believe it would not be source breaking.</div></div></div></blockquote><div><br></div><div>That is indeed something slightly different.</div><div><br></div><div>In an ideal world--and my initial understanding of what you were suggesting--Set and Dictionary would each have a member like `collection`, which would expose the underlying data as a `SetCollection` or `DictionaryCollection` that in turn would conform to `Collection`; meanwhile, Set and Dictionary themselves would not offer methods such as `prefix`, or indexing by subscript, which are not compatible with being unordered. For those who want a particular ordering, there&#39;d be something like `collection(ordered areInIncreasingOrder: (T, T) -&gt; Bool) -&gt; {Set|Dictionary}Collection`.</div><div><br></div><div>What you suggest here instead would be minimally source-breaking. However, I&#39;m unsure of where these guarantees provide benefit to justify the performance cost. Certainly not for `first` or `dropFirst(_:)`, which still yields an arbitrary result which doesn&#39;t make sense for something _unordered_. We *could* have an underscored customization point named something like `_customOrderingPass` that is only invoked from `elementsEqual` or other such methods to pre-rearrange the internal ordering of unordered collections in some deterministic way before comparison. Is that what you have in mind?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><span class=""><div></div><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>I am not arguing that that is necessarily the right approach, just that we need more thought/discussion around what is actually causing the confusion here: The fact that we are assuming an ordering on something where the ordering is undefined.</div></div></blockquote><div><br></div><div>The underlying source of the confusion is clear; I&#39;m trying to encourage us *not* to talk about it here, though, as it&#39;s not a tractable problem for Swift 5.</div></div></div></div></blockquote><br></span></div><div>I find that problematic.</div><div><br></div><div>There are a range of potential solutions that are being offered, from renaming the ‘elementsEqual’ to other things besides ‘lexicographicallyEquals’ to updating our sequence/collection protocols in a minimally source breaking (or even source compatible) way.</div></div></blockquote><div><br></div><div>...to fundamentally changing the protocol hierarchy, which is what I&#39;m encouraging us *not* to talk about. If it&#39;s source-compatible or justifiably limited to breaking only provably harmful behavior, then of course we should discuss it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>Also, I would also argue that if we do find that there are real problems with the sequence protocols, now is the time to fix them before the ABI is set.</div><div><br></div><div>Thanks,</div><div>Jon</div></div></blockquote></div><br></div></div>