So I’m working on a kind of collection wrapper, and hoping to avoid having to 
expose the underlying type of the collection, by instead returning indices of 
AnyIndex. This works fine in one direction, but when it comes time to actually 
use these I have no means of unwrapping them into their original form, this has 
forced me to basically reimplement AnyIndex myself which seems like a lot of 
duplicated code.

For those that haven’t looked at the AnyIndex or similar implementation, there 
are two methods, _unbox() and _unsafeUnbox(), providing access to the 
underlying type, but these are only exposed internally, so aren’t usable 
outside of the guts of stdlib.

What I’m wondering is whether there are any strong reasons against exposing 
these publicly? It could make implementing many wrapper types a lot easier. I 
know the point of AnyIndex and similar is type-erasure, but with the new 
collection model we no longer call any methods of the type-erased wrappers 
themselves, but instead have to pass them around; without unboxing it’s 
essentially impossible for AnyIndex to be reused for new types, which kind of 
restricts them to stdlib only. This basically means that AnyIndex is really 
just a stdlib internal type for implementing the stdlib provided wrapping 
types, if we want to implement our own we have to create our own AnyFooIndex, 
which I’m not sure are as efficient (as stdlib also has access to a few other 
hidden methods for doing this).

If I could just unbox AnyIndex then I could reuse it, rather than reinventing 
the wheel as it were.


This may apply to other stdlib provided wrappers, but AnyIndex is the one that 
has stood out for me, as it seems like there’s no real purpose to me being able 
to wrap values as AnyIndex since there’s very little I can do with them, due to 
all the useful methods being internal only.

To clarify a bit, if we could unbox AnyIndex we could do something like the 
following (many methods omitted for brevity):

        struct AnyIndex : Comparable {
                func unbox<T:Comparable>() -> T?
                func unsafeUnbox<T:Comparable>() -> T
        }

        class MyCollectionBox<Base:Collection> : 
MyCollectionBoxBase<Base.Iterator.Element> {
                let base:Base; init(_ base:Base) { self.base = base }

                var startIndex:AnyIndex { return AnyIndex(base.startIndex) }
                subscript(index:Index) -> Iterator.Element { return 
index.unsafeUnbox() } // method not available
                …
        }

Unless of course I’m doing it completely wrong for Swift 3, which is entirely 
possible. Anyway, I was hoping to discuss it, so a proposal can be considered 
to exposed unboxing methods for AnyIndex (and any other types people think 
should have these abilities).

I realise that perhaps there is a concern that unboxing could be misused, but I 
can’t really think of cases where you would try to, since values such as these 
are only useful when passed back to the type they came from, if you can think 
of a case where unboxing would be misused then feel free to share it!
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to