> On Dec 23, 2016, at 3:28 PM, David Sweeris via swift-evolution 
> <[email protected]> wrote:
> 
> 
>> On Dec 23, 2016, at 2:02 PM, Xiaodi Wu <[email protected] 
>> <mailto:[email protected]>> 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
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to