SE-0329: Clock, Instant, Date, and Duration

My general sense is encoding a value-type value and then decoding the external representation should be equality-preserving, because it makes it easier to reason about the program. For example, maybe I have a big, deeply nested structure that conforms to Equatable and Codable. I can test its round-tripability using plain old XCTAssertEqual. Then I add a Date property at some deeply-nested path in the structure. Suddenly my test starts failing, and I have to jump through hoops to fix it.

(Yes, NaNs destroy equality. But under this proposal, Date is not a floating-point type. We shouldn't be adding more special cases that make it harder to understand how our programs behave.)

If Date is entering the standard library anyway, perhaps we could teach the codable containers about it. For example, add an encode(_ value: Date) requirement to SingleValueEncodingContainer with a default implementation that, for backward compatibility, uses the lossy Double encoding.

Under this design, it becomes possible to extend some codecs to support lossless round trips in a backward-compatible way.

In particular, JSON doesn't limit the number of digits before or after the decimal point. So JSONEncoder and JSONDecoder can be taught (with some work on the underlying NSJSONSerialization) to encode and decode Dates as numbers with perfect accuracy, while maintaining compatibility with older implementations (and with non-Swift JSON codecs).

NSDate is already first-class in property lists, so perhaps the property list codecs could also be enhanced to preserve equality.

8 Likes