[swift-evolution] Possible issue with SE-0166 Swift Archival & Serialization implementation
Itai Ferber
iferber at apple.com
Thu Jun 8 11:46:19 CDT 2017
Sorry, meant for that to be a reply-all.
> On Jun 8, 2017, at 9:45 AM, Itai Ferber <iferber at apple.com> wrote:
>
> Hi Gwendal,
>
>> On Jun 8, 2017, at 8:27 AM, Gwendal Roué via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>
>>>
>>> Le 8 juin 2017 à 16:51, James Froggatt via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at 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 at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170608/8f66eadc/attachment.html>
More information about the swift-evolution
mailing list