Sorry, meant for that to be a reply-all.

> On Jun 8, 2017, at 9:45 AM, Itai Ferber <ifer...@apple.com> wrote:
> 
> Hi Gwendal,
> 
>> On Jun 8, 2017, at 8:27 AM, Gwendal Roué via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> Le 8 juin 2017 à 16:51, James Froggatt via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> I've just been trying out the new Coding protocol, and was rather surprised 
>>> when trying to implement the `encode(to encoder: Encoder)` method.
>>> 
>>> The Swift evolution proposal provides the following example code:
>>> 
>>>   public func encode(to encoder: Encoder) throws {
>>>       // Generic keyed encoder gives type-safe key access: cannot encode 
>>> with keys of the wrong type.
>>>       let container = encoder.container(keyedBy: CodingKeys.self)
>>> 
>>>       // The encoder is generic on the key -- free key autocompletion here.
>>>       try container.encode(latitude, forKey: .latitude)
>>>       try container.encode(longitude, forKey: .longitude)
>>>   }
>>> 
>>> 
>>> Here, container is stored as a `let` value, and uses reference semantics, 
>>> while the proposal also clearly lists these `encode` methods as mutating. 
>>> With the current implementation of the proposal, the container must be 
>>> stored as a `var`, which leads to code like the following:
>>> 
>>>   var container = encoder.singleValueContainer()
>>>   try container.encode(data)
>> 
>> Yes, practically speaking and with latest Swift 4, the container needs to be 
>> declared as `var`.
>> 
>> I admit it's weird, and feels unnatural:
>> 
>>   public func encode(to encoder: Encoder) throws {
>>       // A mutated value that nobody consumes: so weird.
>>       var container = encoder.container(keyedBy: CodingKeys.self)
>>       try container.encode(latitude, forKey: .latitude)
>>       try container.encode(longitude, forKey: .longitude)
>>   }
> Why? It’s perfectly reasonable for the container to maintain some internal 
> state as it’s encoding. It shouldn’t have to sacrifice value semantics for 
> that.
> 
>>> This clearly wont work as expected if the container were to have value 
>>> semantics, and writing code like this feels plain wrong. Is SE-0166 really 
>>> intended to work with referrence-type encoders only?
>> 
>> Actually, it can work with encoder/containers that have value semantics, and 
>> forward the mutations somewhere else (for example to a closure which fills a 
>> mutating container).
>> 
>> But this is again bizarre, and contrieved: 
>> https://github.com/groue/GRDB.swift/blob/15bfe5f6cf76070cfb17216223bdebc6b158d654/GRDB/Record/Persistable%2BEncodable.swift
>>  
>> <https://github.com/groue/GRDB.swift/blob/15bfe5f6cf76070cfb17216223bdebc6b158d654/GRDB/Record/Persistable%2BEncodable.swift>
>> 
>> You make me think that those structs should swiftly be refactored into 
>> reference types.
>> 
>> Gwendal
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to