> 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

Reply via email to