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

Xiaodi Wu xiaodi.wu at gmail.com
Tue Feb 21 14:27:25 CST 2017


Hmm, with respect to both endianness and Jordan's comments re popcount (and
by extension, trailing zeros and leading zeros), I think these go to the
dual purpose of `BinaryInteger` (and its refinement, `FixedWidthInteger`).
Both concede by their very name that they are modeling not merely a numeric
type but one that has a certain machine representation. Endian conversions
aren't numeric operations, but they are appropriately operations that can
be generic over fixed width integers. I'm not convinced (though I haven't
thought about it for too long yet) of what `LittleEndian<Int>` would gain
us.


On Tue, Feb 21, 2017 at 2:12 PM, John McCall via swift-evolution <
swift-evolution at swift.org> wrote:

> On Feb 21, 2017, at 3:08 PM, John McCall via swift-evolution <
> swift-evolution at swift.org> 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.
>
>
> Of course, you would not want LittleEndian<Int> to be directly
> serializable either, because it is not a fixed-size type; but I think the
> underlying point stands.
>
> 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
>
>
>
> _______________________________________________
> 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/20170221/8c050709/attachment.html>


More information about the swift-evolution mailing list