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