<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Feb 21, 2017, at 3:27 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>> wrote:</div><div class=""><div dir="ltr" class=""><div class="">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.</div></div></div></blockquote><div><br class=""></div>It isolates non-native and native integer representations so that you can't easily mix them. It's an extremely common bug in serialization code to forget to byte-swap integers, and we should not naively introduce that bug into Swift by encouraging programmers to use the same type to represent them. The easiest way to achieve that is to try to prevent programmers from ever creating an Int32 whose bytes aren't in native order in the first place. That's not always possible — notably, C doesn't distinguish these in the type system, and there are C APIs that expect to be given a big-endian number — but it's easy enough for BigEndian to have an "init(bitPattern: T)" and a "var bitPattern: T" to cover for cases like that.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, Feb 21, 2017 at 2:12 PM, John McCall via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Feb 21, 2017, at 3:08 PM, John McCall via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><blockquote type="cite" class=""><div class="">On Feb 21, 2017, at 2:15 PM, Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div dir="auto" class=""><div class=""><div class="">Sent from my moss-covered three-handled family gradunza</div></div><div class=""><br class="">On Feb 21, 2017, at 9:04 AM, Jordan Rose <<a href="mailto:jordan_rose@apple.com" target="_blank" class="">jordan_rose@apple.com</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="auto" style="word-wrap:break-word" class="">[Proposal:<span class="m_6405813231599184935Apple-converted-space"> </span><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md" target="_blank" class="">https://github.com/<wbr class="">apple/swift-evolution/blob/<wbr class="">master/proposals/0104-<wbr class="">improved-integers.md</a>]<div class=""><br class=""></div><div class="">Hi, Max (and Dave). I did have some questions about this revision:</div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class="">Arithmetic and <wbr class="">SignedArithmetic protocols have been renamed to Number and SignedNumber.<br class=""></blockquote><br class=""></div><div class="">What happens to NSNumber here? It feels like the same problem as Character and (NS)CharacterSet.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class="">Endian-converting initializers and properties were added to the FixedWidthInteger <wbr class="">protocol.<br class=""></blockquote><br class=""></div>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.<span class="m_6405813231599184935Apple-converted-space"> </span></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">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.</div></div></div></blockquote><div class=""><br class=""></div>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.</div></div></blockquote><div class=""><br class=""></div></span>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.</div><div class=""><br class=""></div><div class="">John.</div><div class=""><div class="h5"><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><br class=""></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class="">John.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">Here's a sketch of such a thing:</div><div class=""><br class=""></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class=""><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">struct LittleEndian<Value: FixedWidthInteger> {</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> private var storage: Value</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> public var value: Value {</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">#if little_endian</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> return storage</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">#else</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> return swapBytes(storage)</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">#endif</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> }</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> public var bitPattern: Value {</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> return storage</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> }</div></div><div class=""><br class=""></div><div class=""> public var asBigEndian: BigEndian<Value> {</div><div class=""> return BigEndian(value: self.value)</div><div class=""> }</div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> public init(value: Value) {</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">#if little_endian</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> storage = value</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">#else</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> storage = swapBytes(value)</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">#endif</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> }</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> public init(bitPattern: Value) {</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> storage = bitPattern</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""> }</div></div></div><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class="">}</div></div></div></blockquote><div dir="auto" style="word-wrap:break-word" class=""><div class=""><div class=""><br class=""></div><div class="">I'm not saying this is the<span class="m_6405813231599184935Apple-converted-space"> </span><i class="">right</i> solution, just that I suspect adding Self-producing properties that change endianness is the wrong one.</div><br class=""></div><div class=""><blockquote type="cite" class=""> /// The number of bits equal to 1 in this value's binary representation.<br class=""> ///<br class=""> /// For example, in a fixed-width integer type with a `bitWidth` value of 8,<br class=""> /// the number 31 has five bits equal to 1.<br class=""> ///<br class=""> /// let x: Int8 = 0b0001_1111<br class=""> /// // x == 31<br class=""> /// // x.popcount == 5<br class=""> var popcount: Int { get<div class=""> }</div></blockquote><br class=""></div><div class="">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.)</div></div></div></blockquote><div class=""><br class=""></div><div class="">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. </div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="auto" style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">(I'm also still not happy with the non-Swifty name, but I see "populationCount" or "numberOfOneBits" would probably be worse.)</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Thanks in advance,</div><div class="">Jordan</div></div></div></blockquote></div>______________________________<wbr class="">_________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class=""></div></blockquote></div><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">______________________________<wbr class="">_________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important" class="">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a></div></blockquote></div><br class=""></div></div></div><br class="">______________________________<wbr class="">_________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>