This proposal is excellent stuff!
If we must have 2 variables to represent 1 value, I'll toss Slice in as a suffix (instead of Portion) into the Bikeshedding mix for secondsSlice & nanosecondsSlice. Could we not do, a single value so that transitioning to a future Int128 type feels more natural?
public struct Duration: Sendable {
typealias Components = (high: Int64, low: Int64)
public var rawValue: Components { get }
}
However, it feels like this is just emblematic of the larger issue: 128-bit storage. (See Below)
TL;DR - Prototype Tests already have (and have for years had) a DoubleWidth<FixedWidthInteger> implementation!
@Philippe_Hausler is right, the answer is to expose the storage-- Nothing against quintillionths, but I wouldn't call it attoseconds I'd jump to RawRepresentable where RawValue == Int128 and expose Duration storage with rawValue.
It's exactly the right thing to use here and (so far) Swift has only continued to flirt with Arbitrary-Precision Integers or even just straight-up Int128. The Swift repo's Tests have sported both a DoubleWidth<FixedWidthInteger> (swift/DoubleWidth.swift.gyb at main Ā· apple/swift Ā· GitHub) and a _BigInt (swift/BigInt.swift at main Ā· apple/swift Ā· GitHub) implementation for years. [NOTE: Result<T> was in Tests before Swift 2 and only moved to the Standard Library in Swift 5. We should revisit this directory's goodies more often.]
Numerics also has some work on Arbitrary-Precision Integers (Arbitrary-precision bigints Ā· Issue #5 Ā· apple/swift-numerics Ā· GitHub) .
When it comes to natural Swift-ness, look-and-feel are paramount to usability. This "2 variables == 1 value" paradigm doesn't feel natural in a language where building up value types is such a focus. At least for me, this is what I want out of Duration:
public struct Duration: Sendable {
public var rawValue: Int128 { get }
}
extension Duration: RawRepresentable { }
I would settle for var rawValue: DoubleWidth<Int64>. If we need to shim this with a new value type under the covers for a few years, let's do that rather than put some "2 variables == 1 value" stuff in the Standard Library. At least that way we could avoid or at least minimize, some potentially code-breaking update in a future Swift with Int128 or Arbitrary-Precision Integers.
I can live with 2 properties; but we didn't do this with Concurrency, nor Distributed Actors or all the various SwiftUI-related proposals-- in those cases if something came up, solve the problem or implement a work-around until LLVM could implement a fix (Evolution is still removing work-arounds on Concurrency features and will be until at least Swift 5.6).
2 properties is a work-around, but it just feels like overhead for implementations.
Anyway, great job everyone! I'm very much looking forward to this one! (assuming we encounter no temporal anomalies or time-loops.)