> On Jun 8, 2017, at 9:45 AM, Itai Ferber <ifer...@apple.com > <mailto: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.
No big trouble, Itai: just that a value type is usually mutated before being used elsewhere. Take this code snippet for example: var a = [1] a.append(2) // if a is not used any longer, something is wrong, don't you agree? And now this other one: var x = SomeValueType() x.append(2) // why would it be different for x? One of the *possible* interpretations of value types is that they are (or look like, if you prefer) purely local, and without side effect. I know that values can hold references and vice-versa, and that the exact distinction between value and reference types is thin, even generally in the hand of the library developer: one can expose a reference type that behaves like a value type, and one can write a value type that obviously hides some references (like the containers above). That's all. No big deal, really. Gwendal
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution