<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On 16 Dec 2016, at 14:51, Anton Zhilin via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">It will be impossible without huge additional overhead.<div class="">I assume that "invalidated" means "no more points to that element".<div class=""><br class=""></div></div><div class="">Consider that an element is inserted in the middle of an Array.</div><div class="">Assuming enough capacity, all iterators after that one will be invalidated.</div><div class="">But all new iterators pointing to the same spots will be valid.</div><div class="">How do you differentiate between the "old" ones and the "new" ones?</div><div class=""><br class=""></div><div class="">I see only one general approach to this:</div><div class="">1. Make iterator type a class</div><div class="">2. Add to the collection, an array of all iterators, which have been created (and are being used)</div><div class="">3. Add a "valid" flag to iterator</div><div class="">4. On most operations on the collection, it will walk through its iterators, marking some as "invalid".</div><div class=""><br class=""></div><div class="">It's a safe way to eliminate some "out of bounds" errors, but it's just utterly rediculous.</div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""><div class="">There was one idea I was exploring but never quite came up with a final design for, which would be the ability for types to "tag" and invalidate values that they return.</div><div class=""><br class=""></div><div class="">In essence, a collection might return an index and tag it as "indices", and a later call to remove, add etc. might invalidate all values tagged as "indices", and provide some guidance on what to do about it. The Swift compiler will make a best effort to track these tags to provide warnings.</div><div class=""><br class=""></div><div class="">I was thinking something like this (heavily cut down):</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>struct Foo : Collection {</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>func index(_ i:Index, offsetBy n:IndexDistance) -> Index @tag("indices") { return i + n }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>@invalidates("indices") func remove(at:Index) { /* Remove an element */ }</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</font></div><div class=""><font face="Monaco" class=""><br class=""></font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var foo = Foo()</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let index = foo.index(foo.startIndex, offsetBy: 5)</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>foo.remove(at: index) // This is fine</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>foo.remove(at: index) // Warning: indices of foo have been invalidated</font></div><div class=""><br class=""></div><div class="">In other words, the variable index is linked (in the compiler, not at run-time) to the type instance that created it by the specified tag "indices". Now, when that type invalidates "indices" that variable is effectively marked as invalid, thus any attempt to use it will produce a warning that it may no longer be valid. Of course in the case of simple indices it should be fine, though technically speaking you're still doing something that could still fail at runtime.</div><div class=""><br class=""></div><div class="">The idea here is that, in the simpler cases at least, the compiler gains some awareness of index invalidation, allowing us to potentially avoid run-time errors entirely; naturally it gets more complex if the indices are passed around, but as long as it is still possible to track where they came from (e.g- if it's a collection held by a class reference) then it can still work. This feature could also be used to detect use of an index for the wrong type or instance; i.e- if two instances have the same index type, indices may not be compatible between the two, currently mixing and matching them isn't a compiler error, but can fail unexpectedly at runtime, though there's probably a simpler solution to that specific case (e.g- some way to make the type checker to treat their indices as if they were different types).</div></body></html>