Sent from my moss-covered three-handled family gradunza

> On Feb 11, 2017, at 5:16 AM, Karl Wagner <razie...@gmail.com> wrote:
> 
> 
>>> On 11 Feb 2017, at 04:23, Brent Royal-Gordon <br...@architechies.com> wrote:
>>> 
>>> On Feb 10, 2017, at 5:49 PM, Jonathan Hull via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> An easier to implement, but slightly less useful approach, would be to have 
>>> methods which take an array of indexes along with the proposed change, and 
>>> then it adjusts the indexes (or replaces them with nil if they are invalid) 
>>> as it makes the update.  For example:
>>> 
>>>    func append(_ element:Element, adjusting: [Index]) -> [Index?]
>>>    func appending(_ element:Element, adjusting: [Index]) -> (Self, [Index?])
>> 
>> This is a very interesting idea. A couple observations:
>> 
>> 1. The problem of adjusting indices is not just a String one. It also 
>> applies to Array, among other things.

You can think of this as a generalization of AttributedString
>> 2. This logic could be encapsulated and reused in a separate type. For 
>> instance, imagine:
>> 
>>    let myStringProxy = IndexTracking(collection: myString, trackedIndices: 
>> [someIndex, otherIndex])
>>    myStringProxy.insert("foo", at: otherIndex)
>>    (someIndex, otherIndex) = (stringProxy.trackedIndices[0], 
>> stringProxy.trackedIndices[1])
>> 
>> Or, with a helper method:
>> 
>>    myString.withTracked(&someIndex) { myStringProxy in
>>        myStringProxy.insert("foo", at: otherIndex)
>>    }

You can't adjust indices in arbitrary RangeReplaceableCollections without 
penalizing the performance of all RangeReplaceableCollections. Also, to do it 
without introducing reference semantics you need to bundle the index storage 
with the collection or explicitly make the collection of indices to be updated 
avAilable input to the range replacement methods. Given the latter, you could 
build something like this to implement the former:

struct IndexTracked<C: RangeReplaceableCollection> 

Also, you probably want his thing to adjust ranges rather than indices because 
otherwise you need to decide whether to adjust an index when there is an 
insertion at that position.   Does it stick to the left or right element?

>> 3. An obstacle to doing this correctly is that a collection's index 
>> invalidation behavior is not expressed in the type system.

I don't see why that's an issue. 

>> If there were a protocol like:
>> 
>>    protocol RangeReplaceableWithEarlierIndexesStableCollection: 
>> RangeReplaceableCollection {}

There's one interesting wrinkle on invalidation I discovered recently: there is 
an important class of indices that are not invalidated as positions when they 
precede the change, but may be invalidated for movement: those that store some 
cached information about following elements, such as transcoded Unicode code 
units. 

>> 
>> That would help us here.
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
> 
> 
> I mentioned this much earlier in the thread. My preferred solution would be 
> some kind of RRC-like protocol where mutating methods returned an associated 
> “IndexDisplacement” type. That IndexDisplacement would store, for each 
> operation, the offset and number of index-positions which have been 
> inserted/removed, and know how to translate an index in the previous state in 
> to one in the new state.
> 
> You would still need to manually adjust your stored indexes using that 
> IndexDisplacement, but it’d be less error-prone as the logic is written for 
> you.
> 
> The standard (non-IndexDisplacement-returning) RRC methods could then be 
> implemented as wrappers which discard the displacement.
> 
> - Karl
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to