> On Apr 12, 2016, at 6:11 PM, Haravikk <[email protected]> wrote:
>
> I’m a +1 for the proposal (but as I’ve implemented a bunch of collections
> recently I’m not sure I’m looking forward to having to update my code to
> reflect the new pattern ;)
>
> But I’m interested by these concerns:
>
>> On 12 Apr 2016, at 17:57, plx via swift-evolution <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> # 1: Relatively Unsafe, Pointer-Like Semantics
>> # 2: Index Invalidation Unrepresented In Type System
>
> It seems to me as though we could solve #1 by solving #2 actually; if we knew
> when indices were invalid, then unless we’re storing .endIndex or using
> .startIndex or .endIndex on an empty collection (rather than .first and
> .last) then there should no issues of the safety of these “pointers" anymore.
FWIW I think “solving” invalidation in the sense of being able to detect
invalidity is useful, but what I’d personally be more interested in is e.g.
something like this:
protocol Collection {
// throw this into the definition:
static var indexCharacteristics: IndexCharacteristics { get }
}
extension RangeReplaceableCollection {
mutating func removeElementsFailing(@noescape predicate: (Element) -> Bool)
{
if Self.indexCharacteristics.removalOnlyInvalidatesRightward() {
// presumptive “fast path”, deleting “back-to-front” to
// avoid making a copy. Just for sake of illustration!
for index in self.indices.dropLast().reverse() where
!predicate(self[index]) {
self.removeAtIndex(index)
}
} else {
// presumptive “slow path”, we rebuild ourself with the failing
elements omitted
self = Self(self.lazy.filter() { predicate($0) })
// ^ assuming self-assignment allowed...
}
}
}
…e.g. some way to get some kind of coarse-grained behavior-characterization of
“what actions invalidate which indices”, thereby allowing one to know when
various approaches will work.
Invalidation is hard and I wouldn’t want anything held up to try and find a
solution first.
>
> The tricky thing is how to handle #2; we can do this at run-time by having
> indices include a reference to their parent (or some kind of ID class), plus
> a copy of a state variable which the collection will use to track
> invalidating changes. If an index is passed to the collection with an
> incorrect reference then it wasn’t for that collection, and if the states
> don’t match then the index was invalidated. But really it’d be better if we
> had some way to do this at compile-time which I think is what you meant; i.e-
> some way for the compiler to track when an index was invalidated between
> being stored and being used, so that passing it into the subscript or other
> methods will produce a warning.
>
> I suppose this could be done using attributes on the return values for index
> generating properties/methods to assign some kind of tag which other methods
> can then mark as having been invalidated, so that anything assigned that tag
> can be considered invalid by the compiler if you try to use a value stored
> before the invalidation. This is something that could be done afterwards I
> think, so hopefully shouldn’t affect the proposal itself. There’ll be limits
> to how far the compiler can track this though, but it could help to avoid
> most of the simpler mistakes at least.
>
> It’d be interesting if the compiler would also trace that an index belongs to
> a collection, to prevent you accidentally using compatible ones with the
> wrong collection when you have several; it’s good practice to check this with
> preconditions, or assertions for performance, but the compiler doing it could
> give more useful errors/advice.
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution