> On Dec 5, 2017, at 2:48 PM, Jordan Rose via swift-dev <swift-dev@swift.org> 
> wrote:
> 
> 
> 
>> On Dec 4, 2017, at 18:48, Brent Royal-Gordon via swift-dev 
>> <swift-dev@swift.org> wrote:
>> 
>>> On Dec 2, 2017, at 12:31 PM, Cao, Jiannan via swift-dev 
>>> <swift-dev@swift.org> wrote:
>>> 
>>> I'd like to discuss the relation between RangeReplaceableCollection and 
>>> MutableCollection
>>> 
>>> MutableCollection is a Collection type that can { set } any element with 
>>> subscript(position: Index). (and also { set } for subscript(range: 
>>> Range<Index>))
>>> 
>>> RangeReplaceableCollection requires a function replaceRange(_:with:)
>>> 
>>> If a type conforms to RangeReplaceableCollection, it means any of its range 
>>> can be replaced, that includes the situation to replace only one element.
>>> So if some type conforms to RangeReplaceableCollection, it is sufficient to 
>>> be a MutableCollection.
>>> So I think the RangeReplaceableCollection should conforms to 
>>> MutableCollection should inherits from MutableCollection.
>> 
>> 
>> I thought this too a couple years ago, but it's not really true. 
>> `MutableCollection` requires not only that you be able to set elements, but 
>> also that when you do so, it doesn't change any of the indices in the 
>> collection. Some collections can't guarantee that. For example, `String` 
>> can't conform to `MutableCollection` because if you set some character in 
>> the middle of the string to a character that's a different size, it might 
>> move characters later in the string to different indices. So Swift lets you 
>> say `myString.replaceSubrange(myRange, with: newCharacters)`, but it doesn't 
>> let you say `myString[myRange] = newCharacters`.
>> 
>> `MutableCollection` and `RangeReplaceableCollection` are very similar in 
>> that they both involve changing a collection. But they are different *kinds* 
>> of changes to a collection, so it makes sense for a collection to support 
>> either one of them without supporting the other.
> 
> MutableCollection's subscript setter is also expected to take constant time 
> (well, proportional to the size of a single element). That may not be the 
> case for a range replacement implementation, even if it turns out the other 
> elements in the collection don't have to move.
> 

The most common example a 
not-constant-time-element-updatable-but-still-range-replaceable-collection 
being String, since graphemes can vary in width in the underlying buffer.

For an example of why this is important, see this optimization for removing 
elements from a RangeReplaceableCollection:

https://github.com/apple/swift/pull/11576/files#diff-6290705036ea8e99c92cd1a8afc9494bR1095

When the collection is both range-replaceable and mutable, it can save time by 
not re-allocating the whole buffer, and just shuffling elements down in-place. 
But it needs to know that swapping two elements takes constant time for this to 
be an improvement and not an accidentally-quadratic disaster.


> Jordan
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

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

Reply via email to