All had a rationale, but that's weaker than a fact -- facts usually don't need nearly as much debate ;-) (although with regard to facts, we live in crazy times... ;-)
Are you familiar with the meaning of & for protocols?
When we split Sequence from Collection, Sequence & Collection is the same thing that is now called Collection.
Ordered and Sorted could be a pure markers, and for Finite, it would make sense to have some sort of length requirement.
All of those could be composed freely, removing the need to have a special protocol for every combination.
That would be somewhat holistic... but alas, as I said: It's to big; just look at the digressions in this thread, which has a rather humble topic.
Exactly. You will have to further declare a OrderedMultiPass protocol and provide appropriate functionality, that only applies to sequences that are both ordered and multi-pass.
Then again, if Ordered and MultiPass aren't type aliases, you demonstrate splitting. And even more than OrderedCollection would require.
extension A & B is not convenient at all. You are not only 'extending an arbitrary type', this would mean every occurrence of A & B will imply extended functionality. That is not the meaning of existentials.
He means that an efficient protocol hierarchy not only allows extension methods, but also requirements, and customization points (requirements with default implementations) so that concrete types can improve on default implementations when they want/can.
Any method defined on an extension A & B (or A where Self: B) can not define any requirement, and can not be customized. Do you understand the consequences?
One half of "extension A where Self: B" is a list of requirements, so I think the confusion is justified ;-)
I'd rather say "you can't declare default implementations in such an extension", which has the same unfortunate effects when an implementer of a protocol wants to "override" a method that was only declared in a protocol extension (Introducing Role Keywords to Protocol Implementations · GitHub).
But you still can declare useful methods, and I can't see why this would be extremely source-breaking (especially for protocols that don't even exist ;-)
I do see that it's now high time that you stopped claiming any right on the time and patience of readers of this thread, and instead took a little bit of your own time to try to understand what other people are telling you.
And they told you much.
This thread has been an interesting exercice since it has debunked, one after the other, most of the misconceptions you initially had about the subject you claim to have a point of view on. You may eventually take also the time to thank all those people that gracefully took the time to explain you when your premises were ill-advised.
It's also high time that you stopped using this assertive tone, which is - I'll grant you that - a tone that is very commonly found in this forum, because you don't use it well. By using this assertive tone to express misconceptions (and you did express many), not only are you failing at fooling experienced readers who know that "assertive" does not mean "true", but you are also bringing inexperienced readers into fallacy pits, and you are finally fooling yourself by thinking that you're on the way to a better Set & Sequence. You are not (yet).
The core team is open to well-defined and well-motivated evolution proposals. This requires work, asking for help when needed, but certainly not claiming any right on this help. Refer to this comment for the true conclusion of this thread.
Excuse me if I mislead you. Let's walk through this once again.
@gwendal.roue already explained what I had in mind, so I will try to give a more detailed answer.
You suggest to use protocol composition and protocol extensions extension A where Self: B to reconstruct the hierarchy. In my previous reply, I was trying to emphasize that protocol extensions are substantially less powerful than protocols themselves. You can't define requirements, associated types, refine semantics of inherited or current reuqirements (i.e {get} -> {get set}, associatedtype A: P -> associatedtype A: Q (Q: P), associatedtype A = Int -> associatedtype A = String, etc). All you can do is declare functions, type aliases, computed properties and... that's pretty much it. It's the same as any extension. It cannot be denied that requirements are more powerful and flexible than declarations. Moreover, everything you declare in extensions will be under the same disadvantages relative to inheriting protocols. You could never make a hierarchy as powerful and flexible as the current Sequence using extensions and protocol composition. You need full-fledged protocols for that. And this means splitting.
No, not declaring methods, but defining requirements
protocol Foo {
func foo()
}
class A: Foo {
func foo() {...}
}
// imagine you can do this
extension Foo {
var value: Int { get set }
}
You would break A, together with all conformances to Foo and its entire hierarchy. Devastating if done retroactively.
IMO, the 2 main points we have to extract from this thread:
Overlooking the Sequence taxon is no trivial question.
We understand and acknowledge the problem being voiced. However, right now it is but a phantom of a possible future problem. The latter doesn't justify ignoring a seed that can sprout, but at present, it is not worth the consequences, convenient or a priority to fully face the issue in question.
Gwendal,
I spent some time thinking wether it would be better to write a private response, but as your last post leaves very little room for interpretation of what you would think about that, I decided not to do so.
Because of the same reason, I'm not pinging you here:
An obvious solution to your issue with this discussion is to leave it, and if that is your choice, I don't want to force you back in. I neither can nor want to lock you out either, but if you are still reading and decide to respond, it might be a good idea not to do so instantly -- that's what I did, and I think it it helped me to write a better and more civil answer.
It's probably right that my tone is flawed, and misunderstanding can arise easily just because posters can't see each others face like in a real talk, or have to reach for a dictionary in the hope that its answer does no damage to what we actually want to express.
I also agree that being thankful is a good idea. But I don't like flattery, so I rather try to express my gratitude by treating discussion partners with respect, and interpret their statements in favor of the author whenever I'm not sure what they want to express.
I have no idea what the majority of readers here thinks regarding Gwendals or my posts, but I hope we can return to a relaxed debate.
For comparison, I just looked at the Wikipedia article for sequence: It has more than 900 edits -- and the text doesn't even talk about generics or operator overloading ;-)
@anthonylatsis: As much as I'd like to continue the strayed discussion, the topic is just to huge...
This is big fish to fry -- but nonetheless, I encourage you to start a separate thread if you want to talk about those properties.
Was the idea of an "Ordered" protocol already discussed or even dismissed? If so, I think I missed it...
However, recently I thought about a purely theoretical (just noticed that it isn't that theoretical: Pitch: ContainmentSet) data structure (I don't know if everyone would even call it a data structure) inspired by mathematical sets that are sometimes expressed by a condition: M = { x element IR | x < 0 } (So M contains all real numbers smaller then 0). Now the data structure does the same:
public struct ConditionMathSet<Element> {
/// The condition whether an Element is contained in this set or not.
private var condition: (Element) -> Bool
/// The only relevant function of this structure
public func contains(_ element: Element) -> Bool {
return condition(element)
}
}
This is once an example of a data structure that is neither a Collection, nor a Sequence and you can truly not iterate it (without going to the address level and checking and interpreting the whole storage, as far as I can see). So it is practically not iteratable because it just don't know the elements in it.
However, if Element is Comparable, the structure is ordered and you can perform sense-full operations on it. The ones I can see are:
get all Elements in it smaller than a certain element func allSmaller(then element: Element) -> ConditionMathSet
the same with greater then and greater-equal then, etc, generalised func all(_ operation: (Element, Element) -> Bool, then element: Element) -> ConditionMathSet
still more generalised fun all(toWhichApplies additionalCondition: (Element) -> Bool)
This includes certain "ranges", so elements smaller then one element and also bigger then another one.
Maybe (hopefully) there are more. I am wondering whether introducing an "Ordered" protocol might be a good addition to swift, if ordered types, like sorted sets or priority lists are added as well. This protocol would have a Key type alias that would need to be Comparable and would determine the ordering. So in an ordered set, the elements are also the keys, but in a priority liked list, the priority is the key. In my opinion arrays are also ordered with the indices being the keys, but in this case it overlaps with the iteratability and the methods from Sequence.
But maybe this has been discussed before and I just don't know about it.
This is obviously no real solution to the problem discussed in this thread, but I could imagine that array conforming to Ordered with these methods and Set not having them might highlight the difference between ordering and iterability and therefor clarify a bit what Sequences methods are about and about what they are not (persistent and defined order).
Here is another similar example (that whole thread is interesting from the perspective of this thread), and my guess is that more situations like this can be found and will reappear until the underlying problem is addressed.
It was mentioned, but afaics, it wasn't actually discussed.
I think it might be even justified to add some granularity and have Sorted as well as Ordered:
There is some desire to have binary search in the stdlib, and and one proposal was rejected because it wanted to add the needed method to every RandomAccessCollection (oh, no: there was even some talk about adding it to more basic protocols).
Operations that depend on sorted-ness and use binary predicates should
not be available on all Collections; they're too easy to misuse,
they're hard to name well, and as Nicola Salmoria has noted, they
would not make any sense at all for a Set.
That is the first (and I think most important) reason for rejection, and it very much resembles the issues we have with Sequences that are not truly ordered (and it even puts the blame on poor Set, as we do all the time ;-).
It looks like I was incorrect about how strong Collection's requirements are supposed to be. I've had some talks and the intent is that the indices' order via Comparable matches the order of index(after:) and, while WackySet as described could still guarantee that for the indices vended per startIndex (generate the full randomized sequence on every call to startIndex), that seems against the spirit of this requirement.
This leads me to agree that Set probably shouldn't have been made a Collection but I don't think it is a strong enough reason to remove conformance, considering.