Personally I prefer the way Optionals currently work (add one bit), but I think 
a better compromise would be the ability to specify arbitrary width integers.

For example, I have a type that stores an optional (so 1-bit overhead) and I 
want to store less than a byte of extra data; if I could specify a 7-bit 
integer then I could limit overhead to a single byte, but currently cannot (at 
least, not without using single Bools which I don't want to do.


For collections there may be other options; for example, storing the 
optionality of values in a separate bitmap, which would reduce memory overhead, 
perhaps types could be added that can do this? For storing lots of optionals 
this would be more efficient on memory, with a slight overhead for double 
optionality checking. Here's a quick example of what I mean:

struct OptionalArray<T> : Collection {
    var values:[T] = [], bitmap:[Bool] = [], defaultValue:T

    init(defaultValue:T) { self.defaultValue = defaultValue }
    init<S:Sequence>(_ theElements:S, defaultValue:T) where S.Iterator.Element 
== T? {
        self.defaultValue = defaultValue

        self.values.reserveCapacity(theElements.underestimatedCount)
        self.bitmap.reserveCapacity(theElements.underestimatedCount)

        for eachElement in theElements {
            self.values.append(eachElement ?? defaultValue)
            self.bitmap.append(eachElement != nil)
        }
    }

    var count:Int { return self.values.count }

    var startIndex:Int { return self.values.startIndex }
    var endIndex:Int { return self.values.endIndex }

    func formIndex(after i:inout Int) { self.values.formIndex(after: &i) }
    func index(after i:Int) -> Int { return self.values.index(after: i) }

    subscript(index:Int) -> T? {
        get { return self.bitmap[index] ? self.values[index] : nil }
        set { self.values[index] = newValue ?? self.defaultValue }
    }
}

You could easily adapt this to store optionality using a default value that's 
unlikely to occur, like so:

struct OptionalArrayAlt<T:Equatable> : Collection {
    var values:[T] = [], defaultValue:T

    init(defaultValue:T) { self.defaultValue = defaultValue }
    init<S:Sequence>(_ theElements:S, defaultValue:T) where S.Iterator.Element 
== T? {
        self.defaultValue = defaultValue
        values.reserveCapacity(theElements.underestimatedCount)
        self.values = theElements.map { return $0 ?? defaultValue }
    }

    var count:Int { return self.values.count }

    var startIndex:Int { return self.values.startIndex }
    var endIndex:Int { return self.values.endIndex }

    func formIndex(after i:inout Int) { self.values.formIndex(after: &i) }
    func index(after i:Int) -> Int { return self.values.index(after: i) }

    subscript(index:Int) -> T? {
        get { let value = self.values[index]; return value == self.defaultValue 
? value : nil }
        set { self.values[index] = newValue ?? self.defaultValue }
    }
}

With the caveat that you either can't store values equal to defaultValue (they 
become nil) or add an assertion/error if that value is stored.

But yeah, I don't think that rolling out the idea to all optionals is a good 
idea; the biggest gains will be had in collections, so any efforts should be 
focused there IMO, and on making custom types align better if possible.
> On 18 Oct 2016, at 21:32, Jean-Daniel via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>> Le 18 oct. 2016 à 21:09, Charlie Monroe via swift-evolution 
>> <swift-evolution@swift.org> a écrit :
>> 
>> Talking about bridging - my guess is that it would mess with NSNotFound 
>> which still has legit use cases even in Swift (when dealing with ObjC APIs) 
>> and is defined as NSIntegerMax at this moment, though its usage is slowly on 
>> the decline…
> 
> Bridge the API that may return NSNotFound to return optional. It would work 
> perfectly well as the nil optional and NSNotFound would have the same binary 
> representation.
> 
> 
>> But there are still many many APIs (mostly C-based) that define some "magic" 
>> constants as (unsigned)(-1), which I believe this would mess with.
>> 
>> Given this, it would IMHO have huge consequences for backward compatiblity.
>> 
>>> On Oct 18, 2016, at 8:54 PM, Kevin Nattinger via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> Part of the beauty of how optionals are implemented in Swift is that the 
>>> compiler doesn’t have to do any magic w.r.t. optionals besides a bit of 
>>> syntactic sugar (`T?` -> `Optional<T>`, `if let x` -> `if let case 
>>> .some(x)`, auto-boxing when necessary, etc.). 
>>> - I strongly dislike the idea of special-casing optionals just to save a 
>>> Byte. 
>>> - Optionals were presented as explicitly removing the need for such a 
>>> sentinel value in the first place.
>>> - There are reasonable cases where such a bit pattern is reasonably 
>>> necessary to the data (e.g. bit fields, RSSI, IP addresses, etc.) and 
>>> removing that value would force ugly workarounds and/or moving to a larger 
>>> int size because of an ill-advised implementation detail.
>>> - If performance or memory is so critical to your specific use case, use a 
>>> non-optional and your own sentinel value. It’s likely no less efficient 
>>> than having the compiler do it that way.
>>> 
>>> (more below)
>>> 
>>>> On Oct 18, 2016, at 11:17 AM, Guoye Zhang via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> Currently, Swift Int family and UInt family have compact representations 
>>>> that utilize all available values, which is inherited from C. However, it 
>>>> is horribly inefficient to implement optional integers. It takes double 
>>>> the space to store [Int?] than to store [Int] because of alignment.
>>>> 
>>>> I propose to ban the top value in Int/UInt which is 0xFFFF... in hex. Int 
>>>> family would lose its smallest value, and UInt family would lose its 
>>>> largest value. Top value is reserved for nil in optionals. An additional 
>>>> benefit is that negating an Int would never crash.
>>>> 
>>>> Interacting with C/Obj-C is a major concern, but since we are already 
>>>> importing some of the unsigned integers as Int which loses half the values,
>>> 
>>> I’d argue those imports are bugs and should be fixed to the correct 
>>> signedness.
>>> 
>>>> one value is not such big a drawback.
>>> 
>>> Unless you happen to need all $width bits.
>>> 
>>>> Alternatively, we could leave current behavior as CInt/CUInt. Converting 
>>>> them to the new Int?/UInt? doesn't generate any instructions since the 
>>>> invalid value already represents nil.
>>> 
>>> Trying to convert an invalid value like that crashes in most of Swift.
>>> 
>>>> 
>>>> With optional integers improved, we could implement safe arithmetic 
>>>> efficiently, or even revisit lenient subscript proposals,
>>> 
>>> I don’t see how losing a particular value has any effect on either of 
>>> those, but it’s possible there’s some theory or implementation detail I’m 
>>> not aware of.
>>> 
>>>> but they are not in the scope of this pitch. Float/Double optionals could 
>>>> also be improved with the similar idea. (Isn't signaling nan the same as 
>>>> nil) Nested optionals such as "Int??" are still bloated, but I don't think 
>>>> they are widely used.
>>>> 
>>>> So what do you think? Can we break C compatibility a bit for better Swift 
>>>> types?
>>> 
>>> We can, and do. C.f. structs, non-@objc classes, and enums not 
>>> RawRepresentable with a C-compatible entity. If anything, this breaks 
>>> compatibility with the rest of Swift.
>>> 
>>>> 
>>>> - Guoye
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to