I should clarify: “works only part of the time” was meant to say that it does not cover all cases. Sometimes a warning will be given and sometimes not. When referring to time I was thinking of the programmer, not of compilation or execution time.
I think that “partially detectable” features increase the cognitive workload rather than decreasing it. If that is the case then I would rather do without. Regards, Rien Site: http://balancingrock.nl Blog: http://swiftrien.blogspot.com Github: http://github.com/Swiftrien Project: http://swiftfire.nl > On 18 Dec 2016, at 12:39, Haravikk <[email protected]> wrote: > > >> On 18 Dec 2016, at 10:04, Rien <[email protected]> wrote: >> >> Solutions that work only part of the time will raise expectations of the >> user only to crush hem later when they fail. >> It will likely generate a number of “bug” reports that must then be >> explained. >> >> I would suggest that functionality like this should only be applied to >> custom types, never on the build-in types. >> >> Regards, >> Rien > > It's not so much that it only works part of the time, but more that in > situations where the "link" would be broken we would need to issue a warning, > which could get annoying given that currently we have no way to suppress > these. > > This is why I stopped working on it as there's a lot of details to hammer > out; I do think it's feasible, but there's a lot to consider. For example, > indices could be treated in a manner similar to non-escaping closures, in > that you can't store or pass them in any way that would break this link to > the parent, unless you use a keyword or attribute to explicitly handle them > in an "unsafe" way. > > So it's not so much that it only works "part of the time", but rather that it > relies on a type of inference, and needs some way to correctly (and usefully) > handle situations where that inference can't be performed, which is why I put > it to one side as it was taking up too much time. > > If I ever do have more time I might put up a more formal thread to discuss it > properly; I do think it's feasible, and possible to make it work well in most > common cases, the question mark is just how best to handle those cases where > either more data is needed, or the warning needs to be overridden somehow. > >>> On 18 Dec 2016, at 10:12, Haravikk via swift-evolution >>> <[email protected]> wrote: >>>> On 16 Dec 2016, at 14:51, Anton Zhilin via swift-evolution >>>> <[email protected]> wrote: >>>> It will be impossible without huge additional overhead. >>>> I assume that "invalidated" means "no more points to that element". >>>> >>>> Consider that an element is inserted in the middle of an Array. >>>> Assuming enough capacity, all iterators after that one will be invalidated. >>>> But all new iterators pointing to the same spots will be valid. >>>> How do you differentiate between the "old" ones and the "new" ones? >>>> >>>> I see only one general approach to this: >>>> 1. Make iterator type a class >>>> 2. Add to the collection, an array of all iterators, which have been >>>> created (and are being used) >>>> 3. Add a "valid" flag to iterator >>>> 4. On most operations on the collection, it will walk through its >>>> iterators, marking some as "invalid". >>>> >>>> It's a safe way to eliminate some "out of bounds" errors, but it's just >>>> utterly rediculous. >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >>> 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. >>> >>> 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. >>> >>> I was thinking something like this (heavily cut down): >>> >>> struct Foo : Collection { >>> func index(_ i:Index, offsetBy n:IndexDistance) -> Index >>> @tag("indices") { return i + n } >>> @invalidates("indices") func remove(at:Index) { /* Remove an >>> element */ } >>> } >>> >>> var foo = Foo() >>> let index = foo.index(foo.startIndex, offsetBy: 5) >>> foo.remove(at: index) // This is fine >>> foo.remove(at: index) // Warning: indices of foo have been invalidated >>> >>> 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. >>> >>> 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). > _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
