<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Apr 12, 2017, at 5:44 PM, Brent Royal-Gordon &lt;<a href="mailto:brent@architechies.com" class="">brent@architechies.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On Apr 12, 2017, at 11:44 AM, Russ Bishop via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><br class=""></div><div class="">* String and Int keys being optional, giving a CodingKey the opportunity to return nil for both at runtime.</div></div></div></blockquote><div class=""><br class=""></div><div class="">This was true in the first public draft, but I believe in this version `stringValue` is no longer Optional.</div></div></div></div></blockquote><div><br class=""></div><div>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.&nbsp;</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="">* Encoder has three functions, but only one may ever be called. This API is the opposite of "pit of success".</div><div class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">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".</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func encode(to encoder: EncodingContainerizer) throws {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>var container = encoder.useContainer(keyedBy: CodingKeys.self)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>try&nbsp;container.encode(name, forKey: .name)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>try&nbsp;container.encode(birthDate, forKey: .birthDate)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div></div></div></div></blockquote><div><br class=""></div><div>We could just completely separate the idea of keyed and unkeyed encoding?</div><div><br class=""></div><div>You may be right that the downsides make an alternative design untenable.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="">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?</div><div class=""><div class=""></div></div></div></blockquote><div class=""><br class=""></div><div class="">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.</div></div></div></div></blockquote><div><br class=""></div><div>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.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class=""><br class=""></div></div><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><div class="">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.</div></div></div></blockquote><div class=""><br class=""></div><div class="">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.&nbsp;</div></div></div></blockquote><div><br class=""></div><div>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.&nbsp;</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="">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).</div></div></blockquote><br class=""></div><div class="">On the contrary, I think we *can* safely leave this to the future. If a future version of Swift and Foundation added:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>@uncoded var foo: Bar</div><div class=""><br class=""></div><div class="">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.</div></div></blockquote><br class=""></div><div>I didn't write that sentence clearly; I was aiming for your meaning that we can leave it for the future.</div><div><br class=""></div><div><br class=""></div><div>Russ</div><br class=""></body></html>