> On Oct 13, 2017, at 6:52 AM, Xiaodi Wu <xiaodi...@gmail.com 
> <mailto:xiaodi...@gmail.com>> wrote:
> 
> You’re welcome to bikeshed the entire API surface area of sequences and 
> collections, but you won’t be the first to explore this area. A number of us 
> looked into this area in the past few years and did not reach a measurable 
> improved result.

I don’t need or want to bikeshed the entire sequence and collection surface 
area, I just want to fix one clear and GLARING issue:

A Set is NOT a sequence.

Note that this goes for dictionaries and any other unordered “sequences" as 
well.

That was in an early draft of my original email, but I dropped it because I was 
afraid people would just stop reading and dismiss the idea out-of-hand without 
considering the problem or arguments. Apparently I should have at least put it 
at the bottom, so sorry if the root issue was unclear.

> Sequences can be ordered or unordered,

You seem to be confusing the English word “sequence” with the (current) Swift 
protocol “Sequence." A sequence is, by definition, ordered. Not enforcing that 
in a protocol does not override the English language, and as this entire thread 
demonstrates, causes issues further on down the line.

> single-pass or multi-pass, finite or infinite, lazy or eager. Not all the 
> combinations of these attributes make sense, but many do. For each 
> combination, a different subset of the sequence algorithms are “useful.” As 
> an example, “last” is not great for an infinite sequence.
> It’s possibly also not what you want for a single-pass sequence.

All of those actually are *sequences*, so it's essentially irrelevant to this 
discussion about not-sequences that conform to Sequence anyway.
 That said, because they are all sequences, there are still a few rational 
behaviors that make logical sense. An infinite loop or nil for infinite.last 
both make sense to me, and it IS what you want for a single-pass set, IMO it's 
a programmer error if the user calls last and they didn't want to burn the set.

> Now, as to the problem discussed here. It’s an orthogonal problem to what you 
> are discussing because, whether or not you reorganize the protocols entirely, 
> there is still going to be confusion about how exactly “elementsEqual” 
> differs from “==“ even for an ordered sequence. The name is clearly 
> problematic in that respect. However, I would argue that the behavior of the 
> method isn’t “improper” and the behavior is not “badly defined.”

Sure, `elementsEqual` isn't perfect, but it's a hell of a lot better than 
`lexicographicallyEquals`. And once you restrict Sequence to properly ordered 
sets, it makes a lot more sense. The problem is a function that compares 
elements "in the same order" when one or both of the sequences doesn't HAVE an 
order.


> 
> On Fri, Oct 13, 2017 at 07:09 Benjamin G <benjamin.garrig...@gmail.com 
> <mailto:benjamin.garrig...@gmail.com>> wrote:
>> +1 on both points. As for your solutions, i see 1/ as the best solution. 
>> Breaking source code that rely on badly defined, or improper behavior isn't 
>> "breaking".  You don't break something that's already half broken.
>> As an app developer relying on swift on my day to day job and making a 
>> living of it, i want to emphasis this: I really don't mind if a language 
>> version change is making me look more carefully on some parts of my code 
>> that i probably had overlooked. 
>> Sure i may pester a bit when the code doesn't compile, but it sure is better 
>> than discovering the weird behavior of a badly defined protocol hierarchy in 
>> customer support.
>> 
>> 
>> On Fri, Oct 13, 2017 at 6:57 AM, Kevin Nattinger via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> –∞
>> 
>> 1. I strongly object to the proposed name. It doesn't make it more clear to 
>> me what the method does, and is misleading at best. Among other issues, 
>> "lexicographical" is defined as alphabet order, and (1) this method applies 
>> to objects that are not Strings, and (2) this method's behavior isn't any 
>> more well-defined for Strings, so that name is even more of a lie than the 
>> original.
>> 
>> 2. This is really just a symptom of a bigger problem. The fact that two Sets 
>> can compare equal and yet return different results for that method (among 
>> too many others) is logically inconsistent and points to a much deeper issue 
>> with Set and Sequence. It is probably about 3 releases too late to get this 
>> straightened out properly, but I'll outline the real issue in case someone 
>> has an idea for fixing it.
>> 
>> The root of the problem is that Set conforms to Sequence, but Sequence 
>> doesn't require a well-defined order. Since Set doesn't have a well-defined 
>> order, a significant portion of its interface is unspecified. The methods 
>> are implemented because they have to be, but they doesn't have well-defined 
>> or necessarily consistent results.
>> 
>> A sequence is, by definition, ordered. That is reflected in the fact that 
>> over half the methods in the main Sequence definition* make no sense and are 
>> not well-defined unless there is a well-defined order to the sequence 
>> itself. What does it even mean to `dropFirst()` in a Set? The fact that two 
>> objects that compare equal can give different results for a 100% 
>> deterministic function is illogical, nonsensical, and dangerous.
>> 
>> * 7/12 by my count, ignoring `_*` funcs but including the `var`
>> 
>> The current contents of Sequence can be cleanly divided into two groups; 
>> those that return SubSequence imply a specific ordering, and the rest do not.
>> 
>>  I think those should be/should have been two separate protocols:
>> 
>> public protocol Iterable {
>>   associatedtype Iterator: IteratorProtocol
>>   func map<T>(...) -> [T] // Iterable where .Iterator.Element == T
>>   func filter(...) -> [Iterator.Element] // Iterable where .Iterator.Element 
>> == Self.Iterator.Element
>>   func forEach(...)
>>   func makeIterator() -> Iterator
>>   var underestimatedCount: Int { get }
>> }
>> 
>> public protocol Sequence: Iterable { // Maybe OrderedSequence just to make 
>> the well-defined-order requirement explicit
>>   associatedtype SubSequence
>>   func dropFirst(...)   -> SubSequence   // Sequence where .Iterator.Element 
>> == Self.Iterator.Element
>>   func dropLast(...)    -> SubSequence   //    " "
>>   func drop(while...)   -> SubSequence   //    " "
>>   func prefix(...)      -> SubSequence   //    " "
>>   func prefix(while...) -> SubSequence   //    " "
>>   func suffix(...)      -> SubSequence   //    " "
>>   func split(...where...)  -> [SubSequence] // Iterable where 
>> .Iterator.Element == (Sequence where .Iterator.Element == 
>> Self.Iterator.Element)
>> }
>> 
>> (The comments, of course, would be more sensible types once the ideas can 
>> actually be expressed in Swift)
>> 
>> Then unordered collections (Set and Dictionary) would just conform to 
>> Iterable and not Sequence, so ALL the methods on those classes would make 
>> logical sense and have well-defined behavior; no change would be needed for 
>> ordered collections.
>> 
>> Now, the practical matter. If this were Swift 1->2 or 2->3, I doubt there 
>> would be a significant issue with actually making this change. 
>> Unfortunately, we're well beyond that and making a change this deep is an 
>> enormous deal. So I see two ways forward.
>> 
>> 1. We could go ahead and make this separation. Although it's a potentially 
>> large breaking change, I would argue that because the methods are 
>> ill-defined anyway, the breakage is justified and a net benefit.
>> 
>> 2. We could try and think of a way to make the distinction between ordered 
>> and unordered "sequences" in a less-breaking manner. Unfortunately, I don't 
>> have a good suggestion for this, but if anyone has ideas, I'm all ears. Or 
>> eyes, as the case may be.
>> 
>> 
>> On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Rename Sequence.elementsEqual
>>> Proposal: SE-NNNN 
>>> <https://gist.github.com/xwu/NNNN-rename-elements-equal.md>
>>> Authors: Xiaodi Wu <https://github.com/xwu>
>>> Review Manager: TBD
>>> Status: Awaiting review
>> Introduction
>> The current behavior of Sequence.elementsEqual is potentially confusing to 
>> users given its name. Having surveyed the alternative solutions to this 
>> problem, it is proposed that the method be renamed to 
>> Sequence.lexicographicallyEquals.
>>  <https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction>
>> [...]
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to