> On Mar 19, 2017, at 12:14 PM, Matthew Johnson <[email protected]> wrote: > > > > Sent from my iPhone > > On Mar 19, 2017, at 10:47 AM, Tony Parker <[email protected] > <mailto:[email protected]>> 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]. - Tony > >> >> - Tony >> >>> On Mar 17, 2017, at 5:56 PM, Matthew Johnson via swift-evolution >>> <[email protected] <mailto:[email protected]>> wrote: >>> >>>> >>>> On Mar 17, 2017, at 6:15 PM, Brent Royal-Gordon <[email protected] >>>> <mailto:[email protected]>> wrote: >>>> >>>>> On Mar 17, 2017, at 3:35 PM, Matthew Johnson <[email protected] >>>>> <mailto:[email protected]>> wrote: >>>>> >>>>>> In all seriousness, I see the design as very slightly weak, in that it >>>>>> makes it easy to forget to pass a context through, but quite acceptable. >>>>> >>>>> Easy for who? I was not requiring Codable types to thread it through at >>>>> all. The context was fully managed by the Encoder / Decoder type. The >>>>> only place Codable types work with the context is as an argument they >>>>> receive. They never pass it when encoding or decoding anything. The >>>>> Encoder / Decoder would need to store the context internally and when >>>>> call is made to encode / decode a ContextAwareCodable it would pass the >>>>> result of a dynamic cast to ContextAwareCodable.Context as the context. >>>> >>>> Oh, I see. Sorry, I missed that when I was looking at your design. >>>> >>>> In practice, in my design, you would only need to manually pass a context >>>> to `encode(_:forKey:with:)` if the context was of a different type than >>>> `self`’s. >>> >>> Oh, I see. I missed that part of your design. I really like it with the >>> shorthands. I’m fully on board with this being the right way to handle >>> contexts now. I think Context should be in the basic Codable protocol. >>> That leaves the question of what to do with NSKeyedArchiver and >>> NSKeyedUnarchiver. I’m not sure what the answer is for those but it would >>> be unfortunate to see the design compromised solely because of a >>> requirement to interoperate with them. >>> >>>> This would probably happen at module or subsystem boundaries. Imagine, for >>>> instance, that your FooKit module (for interacting with the foo.io >>>> <http://foo.io/> web service) needs to encode a GeoKit.Location instance, >>>> but both FooKit and GeoKit need information from a context to encode >>>> themselves properly, and they use different context types. When FooKit >>>> encoded a GeoKit.Location, it could construct and pass a GeoKit context. >>>> >>>> I believe that in your design, unless the FooKit context was a subtype of >>>> the GeoKit context, you wouldn't be able to get GeoKit.Location to do the >>>> right thing. >>> >>> Right. It was assuming only one context would be needed for an entire >>> encoding / decoding process. I don’t know of use cases where one module >>> could meaningfully provide a context to another module unless they were >>> very closely related (i.e. built as parts of the same system) but maybe >>> they do exist. Your design is able to accommodate this very well. >>> >>> I made some compromises to try and diverge from the current proposal as >>> little as possible while still solving the primary use cases I’m aware of. >>> Now that I understand your design I think it has enough advantages that we >>> should go in that direction. And we certainly should not go in the >>> direction of something that requires Any. >>> >>>> >>>> If that weren't the case—if you were encoding a type with a matching >>>> context, or with a `Void` context—you could use the two convenience >>>> methods, which would handle the context argument for you. So threading >>>> contexts would only be necessary in a relatively rare case. >>> >>> Yep, that’s very elegant! >>> >>>> >>>> -- >>>> Brent Royal-Gordon >>>> Architechies >>>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] <mailto:[email protected]> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
