[swift-evolution] [Review] SE-0166: Swift Archival & Serialization

Russ Bishop rbishopjr at apple.com
Wed Apr 12 20:18:08 CDT 2017

> On Apr 12, 2017, at 5:44 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
>> On Apr 12, 2017, at 11:44 AM, Russ Bishop via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> * String and Int keys being optional, giving a CodingKey the opportunity to return nil for both at runtime.
> This was true in the first public draft, but I believe in this version `stringValue` is no longer Optional.

You are correct; I still don't like the fact that you can be in an unkeyed archiver situation and hitting CodingKey adopters that don't provide integer keys. 

>> * Encoder has three functions, but only one may ever be called. This API is the opposite of "pit of success".
> Personally, I'm worried about that too. But I had a lot of trouble coming up with an alternative that didn't violate a more important goal, like "being able to throw errors" or "being compatible with classes".
> Last-ditch suggestion: Change a bunch of names so that, for instance, `Encoder` is instead `EncodingContainerizer`. (That's a terrible name, but "Factory" gives me the hives.) That way, the name of the type gives you a hint that you're supposed to use it to make a container. You might even rename the methods to e.g. `useContainer(keyedBy:)`, which sound a little more stateful and mutually-exclusive.
> 	func encode(to encoder: EncodingContainerizer) throws {
> 		var container = encoder.useContainer(keyedBy: CodingKeys.self)
> 		try container.encode(name, forKey: .name)
> 		try container.encode(birthDate, forKey: .birthDate)
> 	}

We could just completely separate the idea of keyed and unkeyed encoding?

You may be right that the downsides make an alternative design untenable.

>> I don't understand why KeyedEncodingContainer needs all those overloads; automatic conformance to Encodable should be provided for the stdlib types in those overloads so why would they be necessary?
> I argued about this pretty vigorously. They want to avoid the overhead of building an encoder and single-value container and then making several generic calls to encode the value into the container. Personally, I think this is premature optimization of the highest order—particularly since building an encoder and single-value container are often no-ops—but this is the design they chose, and I don't think it's worth rejecting for that alone.

Has someone done performance tests to validate that this is an issue? If nothing else this seems like an implementation detail a conforming type could opt to provide but it shouldn't be required in every implementation.

>> I really strongly dislike mixing up the Unkeyed and Keyed concepts. A type should need to explicitly opt-in to supporting unkeyed and that should be enforced at compile time. Unkeyed encoding is a potential versioning nightmare and should be handled with care.
> I think they've done a reasonable job of putting unkeyed coding in a sharps drawer by making you specifically ask for it and giving it an ugly name. 

Can you clarify what you mean? I see keyed and unkeyed spread across various protocols and types in the proposal. It's front and center. 

>> C#'s serialization attributes are a better and more comprehensive solution but we don't have custom attributes in Swift and property behaviors were deferred. This problem is too important to leave to the future though. If we did ever add custom attributes or if property behaviors get implemented then this design could adopt them incrementally without breaking compatibility (e.g. a serialization transformer behavior that turns a non-Encodable property into an Encodable one, or a behavior that ignores a property for serialization purposes).
> On the contrary, I think we *can* safely leave this to the future. If a future version of Swift and Foundation added:
> 	@uncoded var foo: Bar
> That would be a completely additive change. Until then, there's an irritating but serviceable solution available—write your own CodingKeys enum and let code generation write the `Codable` conformances based on it.

I didn't write that sentence clearly; I was aiming for your meaning that we can leave it for the future.


An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170412/2aad0f3d/attachment-0001.html>

More information about the swift-evolution mailing list