[swift-evolution] [swift-evolution-announce] [Re-Review] SE-0104: Protocol-oriented integers

Patrick Pijnappel patrickpijnappel at gmail.com
Tue Feb 21 17:25:57 CST 2017


 Arbitrary sized signed -1 can have different popcount depending on the
> underlying buffer length (if there is a buffer) even if it’s the same type
> and the same value. Same with leading zeros, as the underlying
> representation is unbounded on the more significant side.


Sensible, why didn't I think of that :).


> Also, arguably shouldn't it be numberOfLeadingZeroBits?
>>
> There is countLeadingZeroBits for that.


I'm mean whether leadingZeroBits should be named numberOfLeadingZeroBits, I
don't see any countLeadingZeroBits.

Joe recently sent an email on behalf of Dave to start this very discussion.


Yeah, that's the one I was responding to! I'm was talking more concretely
about language support.

On Wed, Feb 22, 2017 at 10:18 AM, John McCall via swift-evolution <
swift-evolution at swift.org> wrote:

> On Feb 21, 2017, at 5:39 PM, Dave Abrahams <dabrahams at apple.com> wrote:
> Sent from my moss-covered three-handled family gradunza
>
> On Feb 21, 2017, at 10:08 AM, John McCall <rjmccall at apple.com> wrote:
>
>
> On Feb 21, 2017, at 2:15 PM, Dave Abrahams via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
>
> Sent from my moss-covered three-handled family gradunza
>
> On Feb 21, 2017, at 9:04 AM, Jordan Rose <jordan_rose at apple.com> wrote:
>
> [Proposal: https://github.com/apple/swift-evolution/blob/master/
> proposals/0104-improved-integers.md]
>
> Hi, Max (and Dave). I did have some questions about this revision:
>
> Arithmetic and SignedArithmetic protocols have been renamed
> to Number and SignedNumber.
>
>
> What happens to NSNumber here? It feels like the same problem as Character
> and (NS)CharacterSet.
>
>
> Endian-converting initializers and properties were added to
> the FixedWidthInteger protocol.
>
>
> This is the thing I have the biggest problem with. Endian conversions
> aren't numeric operations, and you can't meaningfully mix numbers of
> different endianness. That implies to me that numbers with different
> endianness should have different types. I think there's a design to explore
> with LittleEndian<Int> and BigEndian<Int>, and explicitly using those types
> whenever you need to convert.
>
>
> I disagree. Nobody actually wants to compute with numbers in the wrong
> endianness for the machine. This is just used for corrections at the ends
> of wire protocols, where static type has no meaning.
>
>
> I think Jordan's suggestion is not that LittleEndian<Int> or
> BigEndian<Int> would be artihmetic types, but that they would be different
> types, primarily opaque, that can be explicitly converted to/from Int.
> When you read something off the wire, you ask for the bytes as one of those
> two types (as appropriate) and then convert to the underlying type.
> Ideally, Int doesn't even conform to the "this type can be read off the
> wire" protocol, eliminating the common mistake of serializing something
> using native endianness.
>
>
> Still, you have to implement those somehow. How do you do that without
> this functionality in the Integer API?  Turtles have to stop somewhere. We
> could de-emphasize these APIs by making them static, but "x.yyyy" already
> *is* a place of reduced emphasis for integers.
>
>
> That's fair.  I don't object to having methods for these as long as they
> aren't the encouraged way of working with byte-swapped integers.
>
> John.
>
>
> John.
>
>
> Here's a sketch of such a thing:
>
> struct LittleEndian<Value: FixedWidthInteger> {
>   private var storage: Value
>
>   public var value: Value {
> #if little_endian
>     return storage
> #else
>     return swapBytes(storage)
> #endif
>   }
>
>   public var bitPattern: Value {
>     return storage
>   }
>
>   public var asBigEndian: BigEndian<Value> {
>     return BigEndian(value: self.value)
>   }
>
>   public init(value: Value) {
> #if little_endian
>     storage = value
> #else
>     storage = swapBytes(value)
> #endif
>   }
>
>   public init(bitPattern: Value) {
>     storage = bitPattern
>   }
> }
>
>
> I'm not saying this is the *right* solution, just that I suspect adding
> Self-producing properties that change endianness is the wrong one.
>
>   /// The number of bits equal to 1 in this value's binary representation.
>   ///
>   /// For example, in a fixed-width integer type with a `bitWidth` value
> of 8,
>   /// the number 31 has five bits equal to 1.
>   ///
>   ///     let x: Int8 = 0b0001_1111
>   ///     // x == 31
>   ///     // x.popcount == 5
>   var popcount: Int { get
>  }
>
>
> Is this property actually useful enough to put into a protocol? I know
> it's defaulted, but it's already an esoteric operation; it seems unlikely
> that one would need it in a generic context. (It's also definable for
> arbitrary UnsignedIntegers as well as arbitrary FixedWidthIntegers.)
>
>
> The whole point is that you want to dispatch down to an LLVM instruction
> for this and not rely on the optimizer to collapse your loop into one.
>
>
> (I'm also still not happy with the non-Swifty name, but I see
> "populationCount" or "numberOfOneBits" would probably be worse.)
>
>
> Thanks in advance,
> Jordan
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170222/3be74d70/attachment.html>


More information about the swift-evolution mailing list