> On Jun 23, 2016, at 15:35, Max Moiseev <[email protected]> wrote:
> 
> Hi Jordan,
> 
>> On Jun 23, 2016, at 1:50 PM, Jordan Rose <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> Hey, standard library folks. Glad we're doing this one. :-)
>> 
>> - I remain unconvinced that defining an Arithmetic that includes both exact 
>> and floating-point numbers is a good idea. All of the arguments from Swift 1 
>> and 2 about why we didn't include this still seem relevant. To phrase it in 
>> generic programming terms, what algorithm would be generic over Arithmetic?
> Steve, I don’t remember exactly why we chose to do it this time. Can you 
> answer?
> 
>> 
>> - What is Integer.init<T: FloatingPoint>(_:) supposed to do if the 
>> floating-point value is larger than the maximum representable integer? 
>> Smaller than the minimum? (As a special case, negative, when the integer 
>> type is unsigned?) Infinity? NaN?
> The same thing it does now — trap.

I think this is worth calling out as a precondition: the value must be within 
the bounds of the integer type. (The implementation may not trap for some 
values slightly outside the integer type, like 0.1 being converted to UInt, but 
it's still not defined.)


>> 
>> - Integer.init<T: Integer>(_:) currently says "if it is representable". It 
>> should say something like "trapping if it is not representable”.
> There is a comment saying that this is the precondition that must be checked 
> by the caller. The initializer will trap but this is the implementation 
> detail, isn’t it?

Ah, of course. My bad.


>> 
>> - I find it odd that Integer.init(clamping:) privileges the bounds of 
>> fixed-width integers. I was going to suggest it should take a range to clamp 
>> to that defaults to the min and max, but that's not implementable for a 
>> BigInt.
> It is always possible to pass bounds as an optional value and default to 
> min…max in .none case.
> So you are suggesting something like `init<T : Integer>(clamping: T, within 
> bounds: Optional<ClosedRange<Self>> = nil)` then?
> I don’t disagree. Looks useful, but I cannot imagine a good real world use 
> for it, except for:
> 
> extension Integer {
>   public func findClosest(to: Self, within bounds: ClosedRange<Self>) {
>     return Self(clamping: to, within: bounds)
>   }
> }

I don't find it any different from the existing requirement. If I'm going from 
a potentially large (absolute) value to a smaller one, it's possible I only 
care about representation, but it's also possible I have a smaller type here 
because of context.

englishPluralIndex = items.count.clamped(to: 0...2)

Maybe I'd go the other way, and say that this isn't a useful requirement. Are 
there algorithms that need this that are generic over Integer? (rather than 
FixedWidthInteger)



> 
>> 
>> - nthWord should count "from least-significant to most-significant" rather 
>> than "from the right”.
> Will this definition work fine with different endiannesses? It needs some 
> thinking, but I see your point.

Yes, "significant" always refers to place values, not to the representation in 
memory/registers.

>> - Why is bitWidth in bits but nthWord in words? (I know there's a good 
>> answer to this, but using them together seems like it will be common.)
> There is a derived property that will return the width in words based on 
> bitWidth and word size.

Got it. May be deserving of a SeeAlso.

>> 
>> - Why are bitwise operations limited to fixed-width integers? I see "The 
>> only difference is that because shifting left truncates the high bits of 
>> fixed-width integers, it is hard to define what a left shift would mean to 
>> an arbitrary-precision integer" further down, but I would just assume it 
>> wouldn't truncate (i.e. it would be a pure multiplication by two).
> Exactly. It won’t truncate and we considered it to be a sufficient difference 
> in behavior to not allow it to be used in the context over all integers.

Hm. I guess that makes sense. My interpretation: the behavior on fixed-width 
integers is well-understood, the behavior on arbitrary-precision integers is 
easy to understand, but the behavior in an algorithm generic over both might be 
problematic. Thanks for the explanation.


>> 
>> - Is there a requirement about left-shifting into the sign bit, for '<<' and 
>> for '&<<‘?
> The current behavior is to not do anything special about the sign bit. So 
> that (64 as Int8) << 1 would result in a -128.
> 
> I should probably add a general note somewhere in the proposal that “unless 
> specifically mentioned, the behavior will remain consistent with the existing 
> implementation”.

Sure. In this case I was asking about the requirement, though. If I use 
something like llvm::APSInt, which has an arbitrary-but-fixed-at-creation 
number of words, does shifting into the sign bit of a signed integer always 
result in a negative number? It never traps or is assumed not to happen?


> 
>> 
>> - What is the ArithmeticOverflow type?
> It is an enum with 2 cases, just like Optional<()>, but with more specific 
> case name. If not for the explicitness, a simple Bool value could have been 
> used.

Please do include this in the proposal. :-)


>> 
>> - When does the remainder operation overflow? (I just can't remember.)
> Discussed in a separate email. The only case where it should trap is 
> ‘division by zero’, so this part is subjected to changes.
>> 
>> - I feel a little weird having "someValue.and(mask)". Maybe bitwiseAnd or 
>> bitwiseAND to be more explicit?
> Doesn’t return type hint at the ‘bitwise' and not logical nature of these 
> operations? Besides, I would expect operators to be used instead of actual 
> protocol functions.

I guess so. It just reads oddly to me.


>> 
>> - maskingShiftLeft/Right seem underspecified in their doc comments. Why 
>> can't the protocol requirement just assume the shift amount has already been 
>> masked, instead of performing the masking themselves? Is it because we won't 
>> be able to optimize that away?
> There is a section about shifts: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md#a-note-on-bit-shifts
>  
> <https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md#a-note-on-bit-shifts>
> Let me know if you think it is insufficient.

I did see this section, but that's about the operator-based interface, not the 
requirements on a model type. I'd like to hear a little more about what the 
expected input range of maskingShiftLeft is and why.

Jordan
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to