[swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

Dmitri Gribenko gribozavr at gmail.com
Tue Apr 12 22:53:57 CDT 2016


On Tue, Apr 12, 2016 at 8:46 PM, plx via swift-evolution
<swift-evolution at swift.org> wrote:
>
> On Apr 12, 2016, at 6:11 PM, Haravikk <swift-evolution at haravikk.me> 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
> <swift-evolution at swift.org> 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...
>       }
>     }
>
>   }

Hi plx,

In case of RangeReplaceableCollection, the index invalidation rules
that we currently have in mind (but haven't documented in public
documentation yet) imply that your fast path is always correct.

Dmitri

-- 
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/


More information about the swift-evolution mailing list