[Re-Review] SE-0104: Protocol-oriented integers


(Joe Groff) #1

Hello Swift community,

The re-review of SE-0104 "Protocol-oriented integers" begins now and runs through February 25, 2017. This proposal was accepted for Swift 3, but was not implemented in time for the release. The revised proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link:
    https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
  
  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe Groff
Review Manager


(Xiaodi Wu) #2

• What is your evaluation of the proposal?

Excellent, even better than the first take. Still not sure about the
`FullWidth` design, but it'll do.

• Is the problem being addressed significant enough to warrant a change to

Swift?

Yes, the previous protocols were confusing and ultimately not very useful.

• Does this proposal fit well with the feel and direction of Swift?

Yes, after overhauling floating point protocols, the rest of the numeric
types are overdue for this change.

• If you have used other languages or libraries with a similar feature, how

do you feel that this proposal compares to those?

I've struggled with the Swift 2/3 integer protocols, does that count? This
proposal is a huge improvement.

• How much effort did you put into your review? A glance, a quick reading,

or an in-depth study?

In-depth study.


(David Sweeris) #3

   • What is your evaluation of the proposal?

Overall, a big +1

I'll 2nd not deprecating the BitwiseOperations protocol, though.

   • Is the problem being addressed significant enough to warrant a change to Swift?

Yes

   • Does this proposal fit well with the feel and direction of Swift?

Yes

   • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

N/A

   • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I followed the thread pretty closely.

- Dave Sweeris

···

Sent from my iPhone

On Feb 17, 2017, at 17:45, Joe Groff <jgroff@apple.com> wrote:


(Haravikk) #4

  • What is your evaluation of the proposal?

Solid +1, though like others I disagree with deprecating BitwiseOperations, and feel it should be integrated into the protocol hierarchy.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Definitely; interpretability of integers and some ambiguity with the types are weaknesses in Swift right now, so the improved design should make a big difference.

  • Does this proposal fit well with the feel and direction of Swift?

Yes.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I've been keeping an eye on the discussion and skimmed the proposal again to hopefully catch any changes.

···

On 18 Feb 2017, at 01:45, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:


(Matthew Johnson) #5

  • What is your evaluation of the proposal?

+1. Very nice!

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes.

  • Does this proposal fit well with the feel and direction of Swift?

Very much so.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Unfortunately, no.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A quick read this time. I read prior versions in depth.

···

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe Groff
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Karl) #6

  • What is your evaluation of the proposal?

+1

I assume the “SignedNumber” protocol is the same as the existing one in the standard library. That is to say, Strideable.Stride will now conform to Number and have operators.

Also minor nitpick, would it be too onerous to require Number.Magnitude to be Comparable? Currently it’s only Equatable and ExpressibleByIntegerLiteral.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Sure is

  • Does this proposal fit well with the feel and direction of Swift?

Yup

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Nope

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Followed previous discussions, read proposal twice.

- Karl


(Zachary Waldowski) #7

• What is your evaluation of the proposal?

Extremely strong +1.

Unlike others, I agree with the proposed deprecation of
BitwiseOperations. It's not pulling its own weight under this new model.
I encourage other reviewers to try, as the proposal suggests, to come up
with a compelling user of just BitwiseOperations.

• Is the problem being addressed significant enough to warrant a
change to Swift?

Yes; it's not as easy to work with integers in Swift 3 as floating
point, which is annoying, since integers are important to binary
programming.

• Does this proposal fit well with the feel and direction of Swift?

The graph of methods and protocols is well-considered, and while it's
probably not mathematically perfect, I could easily see the API being
used to teach binary arithmetic.

• If you have used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?

I've tried (and failed) to use Swift's previous protocols for generic
programming.

• How much effort did you put into your review? A glance, a quick
reading, or an in-depth study?

Thorough reading of previous revisions, glance through of this one.
Thanks for providing the updates section!

Sincerely,

  Zachary Waldowski

  zach@waldowski.me

···

On Fri, Feb 17, 2017, at 08:45 PM, Joe Groff via swift-evolution wrote:


(Jordan Rose) #8

[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. 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.)

(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


(Joe Groff) #9

For the review, Dave asked me to raise a design question on his behalf, since he's on vacation. There are places where the proposal introduces one-case types as a labeling mechanism to distinguish different operations with otherwise the same argument names, for instance:

public enum ReportingOverflow { case reportingOverflow }

protocol Number {
  func adding(_ other: Self) -> Self
}

protocol FixedWidthInteger: BinaryInteger {
  func adding(_ other: Self, _: ReportingOverflow) -> (partialValue: Self, overflow: ArithmeticOverflow)
}

This introduces an otherwise useless type (for which we need to emit metadata, provide documentation for, list in reference documentation and code completion, etc.) and turns the compiler's job of choosing among these operators into an overload resolution problem rather than a simpler name lookup problem. In other places, particularly when a type imported from Cocoa has multiple nullary initializers, we already use the convention of a Void-typed labeled argument, which would look like this:

protocol FixedWidthInteger: BinaryInteger {
  func adding(_ other: Self, reportingOverflow: Void) -> (partialValue: Self, overflow: ArithmeticOverflow)
}

The call syntax is less aethestically pleasing, no doubt (`adding(5, reportingOverflow: ())`), but that's arguably a problem we should address at the language level given that we already have APIs that look like that. The tradeoff of ugly syntax, which we can potentially beautify over time, in return for less "stuff" in the standard library, which we can't get rid off once the dylib is burned into billions of user devices, is worth considering.

-Joe


(Howard Lovatt) #10

The re-review of SE-0104 "Protocol-oriented integers" begins now and runs
through February 25, 2017. This proposal was accepted for Swift 3, but was
not implemented in time for the release. The revised proposal is available
here:

https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md

• What is your evaluation of the proposal?

Well worth while. Few nit picks:

  1. Number.init? Description should say BinaryInteger not floating-point.
  2. Number should document that mutating versions of operators can
overflow.
  3. SignedNumber should document that negate and unary `-` can overflow.
  4. SignedNumber, it is weird that `signum` is a function when other
similar things, e.g. `magnitude`, are properties.
  5. Not worth representing `DoubleWidth` as an enumeration, it is obscure
and therefore will only confuse people.
  6. It would be better to put the 'extra' operations into the protocols
and provide default implementations, otherwise they are difficult to find.

• Is the problem being addressed significant enough to warrant a change to
Swift?

Yes, the current design has not served my purpose on more than one occasion

• Does this proposal fit well with the feel and direction of Swift?

Yes

• If you have used other languages or libraries with a similar feature,
how do you feel that this proposal compares to those?

Yes, this proposal is similar to what other languages provide, e.g. Scala.
In Scala however they tackle the `conversion problem as well in their
`traits heirarchy. I guess this could be added at a later date.

• How much effort did you put into your review? A glance, a quick reading,
or an in-depth study?

Read the proposal, have used similar features in other languages, and have
had trouble with Swift's current heirarchy.

···

--
-- Howard.


(plx) #11

+1 on most of it, with some minor quibbles.

First quibble: between `Number` and `Arithmetic` I’d prefer `Arithmetic`; this is 50/50 aesthetics and concern about clarity vis-a-vis `(NS)Number`, `(NS)DecimalNumber`, and so on.

Next quibble: `Magnitude` being defined as the “absolute value” of the underlying type seems a bit nonsensical if e.g. `Number` is intended to be adoptable by complex numbers (let alone quaternions, matrices, and whatnot). What *would* a conforming complex # implementation be expected to return as e.g. `(1-i).magnitude`? For the intended use this seems like it needs to be moved out of the basic `Number`/`Arithmetic` protocol into a new protocol.

Final quibble: is there an official stance as to whether or not `Number/`Arithmetic` is allowed to have non-commutative multiplication? I see would prefer any policy on this be explicitly documented.

If `Number`/`Arithmetic` *is* intended to allow adopters with non-commutative multiplication, then it’s seemingly missing an overridable method:

- this exists: `x *= y` (presumably equivalent to `x = x * y`)
- this doesn't: `x =* y` (presumably equivalent to one of `x = y * x` *or* `y = x * y`, your preference)

…(alternative operator names are fine, the important bit is an in-place multiplication-from-the-left). Not necessary, but still nice to have for non-commutative adoptees.

PS: I suspect this ship has *long* sailed but I suspect that it would be better in the long run to go the route of `Addable`, `Multipliable`, etc., and use typealiases to define common groupings thereof; note that once you remove `Magnitude`, the only difference between:

- `Number` (as defined)
- `typealias Number = Equatable & ExpressibleByIntegerLiteral & Addable & Multipliable`

…would be `init?<T : BinaryInteger>(exactly source: T)`.

Although this is an extra method and thus extra “semantics”, I think there’s a perfectly-reasonable argument that—at least informally—the *semantics* of `init?<T : BinaryInteger>(exactly source: T)` are already-implied by the adoption of `ExpressibleByIntegerLiteral`; in fact, are there any types that *could* reasonably adopt `ExpressibleByIntegerLiteral` but *could not* reasonably implement `init?<T : BinaryInteger>(exactly source: T)`?

Anyways, that’s my 2c on this: the Integer-related aspects seem fine, but I have quibbles vis-a-vis the foundational protocol.

···

On Feb 17, 2017, at 7:45 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The re-review of SE-0104 "Protocol-oriented integers" begins now and runs through February 25, 2017. This proposal was accepted for Swift 3, but was not implemented in time for the release. The revised proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link:
    https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
  
  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe Groff
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ben Cohen) #12

Hi everyone,

The core team met and reviewed the discussion of this proposal so far, and had the following mid-review feedback to relay back to the list:

Regarding the “Number” protocol: it was felt this is likely to cause confusion with NSNumber, given the NS-prefix-dropping versions of other Foundation types indicate a value-typed concrete type equivalent, which this won’t be. The recommendation is to use “Numeric" instead.
Regarding the question of the trailing argument to distinguish overflow-checking vs expanding versions of multiplied: rather than add an enum or use the void trick in order to do this via arguments, it is better to just distinguish the two functions via different base names.
Regarding restoring the BitwiseOperations protocol – the team feels that the bitset use case can be modeled with SetAlgebra rather than retaining a protocol with only bitwise operators.
popcount – although this is a term of art, in general it’s best to avoid abbreviations, so the suggestion is to rename it populationCount, which also helps settle whether the “c” should be capitalized and confusion over the other meaning of “pop".

- Ben

···

On Feb 17, 2017, at 5:45 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The re-review of SE-0104 "Protocol-oriented integers" begins now and runs through February 25, 2017. This proposal was accepted for Swift 3, but was not implemented in time for the release. The revised proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link:
    https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
  
  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe Groff
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ben Cohen) #13

Hi everyone,

The core team met and reviewed the discussion of this proposal so far, and had the following mid-review feedback to relay back to the list:

Regarding the “Number” protocol: it was felt this is likely to cause confusion with NSNumber, given the NS-prefix-dropping versions of other Foundation types indicate a value-typed concrete type equivalent, which this won’t be. The recommendation is to use “Numeric" instead.
Regarding the question of the trailing argument to distinguish overflow-checking vs expanding versions of multiplied: rather than add an enum or use the void trick in order to do this via arguments, it is better to just distinguish the two functions via different base names.
Regarding restoring the BitwiseOperations protocol – the team feels that the bitset use case can be modeled with SetAlgebra rather than retaining a protocol with only bitwise operators.
popcount – although this is a term of art, in general it’s best to avoid abbreviations, so the suggestion is to rename it populationCount, which also helps settle whether the “c” should be capitalized and confusion over the other meaning of “pop".

- Ben

···

On Feb 17, 2017, at 5:45 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The re-review of SE-0104 "Protocol-oriented integers" begins now and runs through February 25, 2017. This proposal was accepted for Swift 3, but was not implemented in time for the release. The revised proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md

Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

  https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

  Proposal link:
    https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
  
  Reply text

  Other replies

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Joe Groff
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Hugo Hennies) #14

• What is your evaluation of the proposal?

Very good. It's a much needed improvement to the language's integer protocols and type hierarchy.

I would argue against the deprecation of the BitwiseOperations protocol though. I believe a bitset type would be a good candidate for conformance to this protocol while at the same time not being an integer at all.

I do not propose to a standard library implementation of a bitset type, but I think the standard protocols should let themselves to be easily extended and implemented by user types. Assuming only integers will ever have bitwise operations might limit users and force them to write duplicate code.

• Is the problem being addressed significant enough to warrant a change to Swift?

Yes, the previous protocols were confusing and didn't let themselves very well to generic programming over the various integer types of the language.

• Does this proposal fit well with the feel and direction of Swift?

Yes, this proposal very much captures the feel of the language and it's standard library.

• If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I haven't used a language before that I could compare effectively with the features proposed here.

• How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

A quick reading.


(Dave Abrahams) #15

[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.

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.

···

Sent from my moss-covered three-handled family gradunza

On Feb 21, 2017, at 9:04 AM, Jordan Rose <jordan_rose@apple.com> wrote:

(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


(Max Moiseev) #16

I assume the “SignedNumber” protocol is the same as the existing one in the standard library. That is to say, Strideable.Stride will now conform to Number and have operators.

SignedNumber will *not* be the same. It is just the same name.
Stride will have operators, yes. Strideable in general will not, unless it’s a _Pointer. (you can find the current implementation prototype here <https://github.com/apple/swift/blob/new-integer-protocols/stdlib/public/core/Stride.swift.gyb>).

Also minor nitpick, would it be too onerous to require Number.Magnitude to be Comparable? Currently it’s only Equatable and ExpressibleByIntegerLiteral.

Magnitude is supposed to conform to Arithmetic (or Number, or whatever it ends up being called), but the recursive constraints feature is missing, therefore we constrained it with the protocols that Arithmetic itself refines.

Why would you want Comparable?

Max

···

On Feb 18, 2017, at 12:02 PM, Karl Wagner via swift-evolution <swift-evolution@swift.org> wrote:


(John McCall) #17

Sent from my moss-covered three-handled family gradunza

[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.

John.

···

On Feb 21, 2017, at 2:15 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:
On Feb 21, 2017, at 9:04 AM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Max Moiseev) #18

The re-review of SE-0104 "Protocol-oriented integers" begins now and runs through February 25, 2017. This proposal was accepted for Swift 3, but was not implemented in time for the release. The revised proposal is available here:

  https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md

  • What is your evaluation of the proposal?

Well worth while. Few nit picks:

  1. Number.init? Description should say BinaryInteger not floating-point.

I’ll update the proposal.

  2. Number should document that mutating versions of operators can overflow.
  3. SignedNumber should document that negate and unary `-` can overflow.

Documentation changes noted. Thanks!

  4. SignedNumber, it is weird that `signum` is a function when other similar things, e.g. `magnitude`, are properties.

I think of it as: magnitude is something the number ‘has’ whereas signum is a completely new thing of the same type.

  5. Not worth representing `DoubleWidth` as an enumeration, it is obscure and therefore will only confuse people.
  6. It would be better to put the 'extra' operations into the protocols and provide default implementations, otherwise they are difficult to find.

They are defined as protocol extensions, therefore they should be discoverable through completion and in the generated source code. Or what do you mean by ‘difficult to find’?

Thanks for the feedback!

···

On Feb 21, 2017, at 3:05 PM, Howard Lovatt via swift-evolution <swift-evolution@swift.org> wrote:

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes, the current design has not served my purpose on more than one occasion

  • Does this proposal fit well with the feel and direction of Swift?

Yes

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Yes, this proposal is similar to what other languages provide, e.g. Scala. In Scala however they tackle the `conversion problem as well in their `traits heirarchy. I guess this could be added at a later date.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Read the proposal, have used similar features in other languages, and have had trouble with Swift's current heirarchy.
--
-- Howard.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #19

For the review, Dave asked me to raise a design question on his behalf,
since he's on vacation. There are places where the proposal introduces
one-case types as a labeling mechanism to distinguish different operations
with otherwise the same argument names, for instance:

public enum ReportingOverflow { case reportingOverflow }

protocol Number {
  func adding(_ other: Self) -> Self
}

protocol FixedWidthInteger: BinaryInteger {
  func adding(_ other: Self, _: ReportingOverflow) -> (partialValue: Self,
overflow: ArithmeticOverflow)
}

This introduces an otherwise useless type (for which we need to emit
metadata, provide documentation for, list in reference documentation and
code completion, etc.) and turns the compiler's job of choosing among these
operators into an overload resolution problem rather than a simpler name
lookup problem. In other places, particularly when a type imported from
Cocoa has multiple nullary initializers, we already use the convention of a
Void-typed labeled argument, which would look like this:

protocol FixedWidthInteger: BinaryInteger {
  func adding(_ other: Self, reportingOverflow: Void) -> (partialValue:
Self, overflow: ArithmeticOverflow)
}

The call syntax is less aethestically pleasing, no doubt (`adding(5,
reportingOverflow: ())`), but that's arguably a problem we should address
at the language level given that we already have APIs that look like that.
The tradeoff of ugly syntax, which we can potentially beautify over time,
in return for less "stuff" in the standard library, which we can't get rid
off once the dylib is burned into billions of user devices, is worth
considering.

+1. That seems like the wiser (if less "clever") solution.

···

On Tue, Feb 21, 2017 at 1:51 PM, Joe Groff via swift-evolution < swift-evolution@swift.org> wrote:


(Colin Barrett) #20

I'm not sure exactly where the bar is, but chiming in that recently, in
implementing generic succinct data structures as an exercise, I needed to
define exactly this operation generically.

-Colin

···

On Tue, Feb 21, 2017 at 6:29 PM Max Moiseev via swift-evolution < swift-evolution@swift.org> wrote:

On Feb 21, 2017, at 3:05 PM, Howard Lovatt via swift-evolution < > swift-evolution@swift.org> wrote:

The re-review of SE-0104 "Protocol-oriented integers" begins now and runs
through February 25, 2017. This proposal was accepted for Swift 3, but was
not implemented in time for the release. The revised proposal is available
here:

https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md

• What is your evaluation of the proposal?

Well worth while. Few nit picks:

  1. Number.init? Description should say BinaryInteger not floating-point.

I’ll update the proposal.

  2. Number should document that mutating versions of operators can
overflow.
  3. SignedNumber should document that negate and unary `-` can overflow.

Documentation changes noted. Thanks!

  4. SignedNumber, it is weird that `signum` is a function when other
similar things, e.g. `magnitude`, are properties.

I think of it as: magnitude is something the number ‘has’ whereas signum
is a completely new thing of the same type.

  5. Not worth representing `DoubleWidth` as an enumeration, it is obscure
and therefore will only confuse people.
  6. It would be better to put the 'extra' operations into the protocols
and provide default implementations, otherwise they are difficult to find.

They are defined as protocol extensions, therefore they should be
discoverable through completion and in the generated source code. Or what
do you mean by ‘difficult to find’?

Thanks for the feedback!

• Is the problem being addressed significant enough to warrant a change to
Swift?

Yes, the current design has not served my purpose on more than one
occasion

• Does this proposal fit well with the feel and direction of Swift?

Yes

• If you have used other languages or libraries with a similar feature,
how do you feel that this proposal compares to those?

Yes, this proposal is similar to what other languages provide, e.g. Scala.
In Scala however they tackle the `conversion problem as well in their
`traits heirarchy. I guess this could be added at a later date.

• How much effort did you put into your review? A glance, a quick reading,
or an in-depth study?

Read the proposal, have used similar features in other languages, and have
had trouble with Swift's current heirarchy.
--
-- Howard.
_______________________________________________
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