Sorry, meant for that to be a reply-all.
> On Jun 8, 2017, at 9:45 AM, Itai Ferber <[email protected]> wrote: > > Hi Gwendal, > >> On Jun 8, 2017, at 8:27 AM, Gwendal Roué via swift-evolution >> <[email protected] <mailto:[email protected]>> wrote: >> >>> >>> Le 8 juin 2017 à 16:51, James Froggatt via swift-evolution >>> <[email protected] <mailto:[email protected]>> 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 >> [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
