[swift-evolution] [Proposal] Foundation Swift Encoders

Brent Royal-Gordon brent at architechies.com
Tue Apr 4 23:05:36 CDT 2017

> On Apr 4, 2017, at 7:37 PM, Ben Rimmington via swift-evolution <swift-evolution at swift.org> wrote:
>> On 4 Apr 2017, at 22:43, Itai Ferber wrote:
>>> On 4 Apr 2017, at 1:57, Brent Royal-Gordon wrote:
>>> I like the separation between keyed and unkeyed containers (and I think "unkeyed" is a good name, though not perfect), but I'm not quite happy with the unkeyed container API. Encoding a value into an unkeyed container appends it to the container's end; decoding a value from an unkeyed container removes it from the container's front. These are very important semantics that the method names in question do not imply at all.
>> I think that consistency of phrasing is really important here, and the action words "encode" and "decode" are even more important to connote than the semantics of pushing and popping.
>> (Note that there need not be specific directionality to an unkeyed container as long as the ordering of encoded items is eventually maintained on decode.) But on a practical note, names like encodeAtEnd and decodeFromFront (or similar) don't feel like they communicate anything much more useful than the current encode/decode.
> If the unkeyed containers are FIFO then I suggest:
> * a `QueuedEncodingContainer` protocol with `enqueue(_:)` methods,
> * a `QueuedDecodingContainer` protocol with `dequeue(_:)` methods.

These are FIFO, yes, but I don't think describing them as "queues" is helpful. They aren't used in the way you normally think of a queue being used; usually a queue allows enqueueing and dequeueing operations to be intermixed, but that's not the case here.

The more I think about it, the more I like `encodeNext(_:)` and `decodeNext(_:)`. They suggest that each call advances an internal position, but they don't waste a lot of time talking about a "start" or "end", or imply that there's a "front" or "back". Which value are you adding? The next one. Which are you decoding? The next one.

Thinking about it a little more, I'd suggest a couple more changes to it:

* Rename `isAtEnd` to `isEmpty`. That harmonizes with `Collection` APIs.

* Document `count` as returning the number of *remaining* elements, if known. That makes the `count` always useful.

* Possibly, make `decodeNext(_:)` (or `decode(_:)`) return `T?` and `decodeNextIfPossible(_:)` return `T??`, with the (outer) `nil` indicating that you've retrieved all of the elements. That would let you use a `while let` loop, which is a bit more idiomatic:

	while let elem = try container.decodeNext(Element.self) {

Brent Royal-Gordon

More information about the swift-evolution mailing list