[swift-evolution] Overloading Generic Types

David Sweeris davesweeris at mac.com
Wed Feb 22 12:20:56 CST 2017


> On Dec 23, 2016, at 3:28 PM, David Sweeris via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On Dec 23, 2016, at 2:02 PM, Xiaodi Wu <xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>> wrote:
>> 
>> I don't currently have a use for it, but I can certainly see how this might be useful to some people.
>> 
>> As a side note, though, it seems like the consensus is that the optimization shown in your specific example, which is provided by std::vector<bool> in C++, is now widely regarded as a poor design choice. See, for instance, <http://stackoverflow.com/questions/17794569/why-is-vectorbool-not-a-stl-container <http://stackoverflow.com/questions/17794569/why-is-vectorbool-not-a-stl-container>>, <https://isocpp.org/blog/2012/11/on-vectorbool <https://isocpp.org/blog/2012/11/on-vectorbool>>, and <http://www.gotw.ca/publications/N1211.pdf <http://www.gotw.ca/publications/N1211.pdf>>.
>> 
>> It would be interesting to see if you can come up with a use case where the proposed feature is a clear win as opposed to just having a totally separate type that makes clear it's not quite the same thing under the hood (in your example, something like `BitArray`).
> 
> I'm starting to think my original motivation might’ve had something to do with normally needing storage for both some property and a T, but not needing (local) storage for said property if T conformed to a protocol which itself already required conforming types to have that property? Or maybe as a way to have the “bottom” variable in a hierarchy of wrapper types to break the “reference cycle” for some property? (Come to think of it, those could be the same thing)
> 
> That was (and is) an odd project... Anyway, it's been a while since I've thought about it. I'll try to find time today to poke through some old code and see if still have a copy of what I’d gotten stuck on.
> 
> And thanks for those links :-)

This isn’t what I’d been thinking of earlier, but what about Optionals? I seem to recall reading somewhere that an Optional<Unsafe*Pointer> took up the same amount of storage as the Unsafe*Pointer itself because the compiler could use Unsafe*Pointer's null-pointer value to represent the `.none` case. What if we extended that to any type that’s ExpressibleByNilLiteral & Equatable? I *think* we’d have to introduce the feature of “computed cases” to actually implement it without compiler magic (and getting rid of compiler magic for Optional<Unsafe*Pointer> would be half the point, in this instance):

enum Optional<T> : ExpressibleByNilLiteral {...} // Same as now
enum Optional<T> : ExpressibleByNilLiteral where T: ExpressibleByNilLiteral & Equatable {
    case some(T) // Only one case, so storage-wise, nothing extra is needed
    init(_ value: T) { self = .some(value) }
    init(nilLiteral: ()) { self = .some(nil as T) }
    /* "var case `label`" declares a "computed case", a case that doesn't needs
     * any extra bits to "store".
     * In the return value, `.matches` tells the pattern matcher if there's a
     * match, and `.associatedValue` carries any associated values. It probably
     * shouldn't even exist in this example, since we're modeling `.none` rather
     * than `.none(Void)`, but Swift doesn't currently allow for single-element
     * tuples. In practice, all this means is that we'd need to consider `case
     * label(Void)` to be the same as `case label`.
     */
    var case none: (matches: Bool, associatedValue: Void) {
        switch self {
        case .some(let value): return (value == nil as T, ())
        }
    }
}

- Dave Sweeris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170222/b4978556/attachment.html>


More information about the swift-evolution mailing list