[swift-evolution] [Proposal] Foundation Swift Archival & Serialization

Brent Royal-Gordon brent at architechies.com
Sun Mar 19 15:38:33 CDT 2017

> On Mar 19, 2017, at 12:21 PM, Tony Parker <anthony.parker at apple.com> wrote:
>> On Mar 19, 2017, at 12:14 PM, Matthew Johnson <matthew at anandabits.com <mailto:matthew at anandabits.com>> wrote:
>> On Mar 19, 2017, at 10:47 AM, Tony Parker <anthony.parker at apple.com <mailto:anthony.parker at apple.com>> wrote:
>>> Hi Matthew, Brent,
>>> I see why you are asking for this Context parameter, but putting it into the basic Codable protocol introduces too much conceptual overhead. There are too many benefits to keeping adoption to just one protocol, including discoverability, ease of use, reducing the need for overloads on protocols elsewhere, and more. Supporting this one use case does not outweigh those benefits, especially considering I expect that most library code would not use it (as you say: it would be weird to pass this context between modules).
>>> Can you figure out a way to get the context info passed through the encoder/decoder instead? It would make more sense as something optionally retrieved from the encoder/decoder that was set at the top level.
>> Hi Tony.  I can see the argument that the this is a feature that should be relatively rarely used and thus should have as simple a design as possible.
>> If you feel like the impact of threading a typed context on the API surface area is too heavy you could just add a `var context: Any? { get }` requirement to Encoder and Decoder.  The expectation is that encoders and decoders would accept a context in the top level call and make it available to all Codable types.  This would solve the problem with minimal API impact at the cost of the ability to statically verify that all types receive the context they need to encode / decode correctly.
>> I much prefer the static safety but having a solution is better than not having one.  :)
> The Any context property is reasonable, but it would be nice to find something in the middle. =)
> One other possibility is that we define a user info dictionary instead, with a custom key type that can be extended (much like our string enumerations). In general I haven’t been a fan of the user info pattern in Swift because of the necessity to cast, but as you say it’s better than nothing. e.g. userInfo : [CodingUserInfoKey: Any].

I hate casting out of Any, and I strongly believe we should support multiple contexts, so personally, I'd prefer something typed:

	protocol Encoder {
		// Retrieve the context instance of the indicated type.
		func context<Context>(ofType type: Context.Type) -> Context?
		// This context is visible for `encode(_:)` calls from this encoder's containers all the way down, recursively.
		func addContext<Context>(_ context: Context, ofType type: Context.Type)
	// Likewise on Decoder
	// Encoder and decoder classes should accept contexts in their top-level API:
	open class JSONEncoder {
		open func encode<Value : Codable>(_ value: Value, withContexts contexts: [Any] = []) throws -> Data

Brent Royal-Gordon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170319/a2652b84/attachment.html>

More information about the swift-evolution mailing list