Hi Slava,
Thanks for your comments!
On 16 Mar 2017, at 13:50, Slava Pestov wrote:
Hi Itai,
I’m wondering what the motivation is for keeping this as part of
Foundation and not the standard library. It seems like you’re
landing an implementation of this in the Foundation overlay on master,
and another copy of all the code will have to go into
swift-corelibs-foundation. This seems suboptimal. Or are there future
plans to unify the Foundation overlay with corelibs-foundation
somehow?
This has to be part of Foundation because `Data`, a Foundation type, is
one of the primitive types of serialization. This will be doubly true if
we decide to add `Date` as another primitive type.
I agree that this is suboptimal at the moment, but we will work to find
a way to keep the work in sync in a reasonable manner.
Also the implementation uses some Foundation-isms (NSMutableArray,
NSNumber) and it would be nice to stick with idiomatic Swift as much
as possible instead.
Using the Foundation framework is just as idiomatic in Swift… ;)
In this specific case, we need collections with reference semantics
(`NSMutableArray` and `NSMutableDictionary`) and a concrete type-erased
number box (`NSNumber`); theres’s no reason to reinvent the wheel if
we already have exactly the tools we need.
The reference implementation at the moment goes through
`JSONSerialization`, which affects the specifics of its implementation.
This may change in the future.
Finally you should take a look at the integer protocol work
(https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
<https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md>)
to replace the repetitive code surrounding primitive types, however I
don’t know if this has landed in master yet.
As mentioned in other emails, the list of primitive types was carefully
chosen because we need to have a concrete list of types which consumers
can rely on being supported, and that `Encoder`s and `Decoder`s know
they _must_ support.
Specifically:
1. For binary formats, the difference between an `Int16` and an `Int64`
is significant. The `Encoder` would need to know that it’s received
one type or another, not just a `FixedWidthInteger`; this would involve
a runtime check of the concrete type of the argument
2. Any type can conform to these protocols — nothing is preventing me
from writing an `Int37` type conforming to `FixedWidthInteger` and
passing it in. Most encoders would really not know what to do with this
type (especially ones with binary formats), but the failure would be a
runtime one instead of a static one
* A concrete example of this is the `FloatingPoint` protocol.
`Float80` conforms to the protocol, but no common binary format I’ve
seen supports 80-bit floating-point values. We’d prefer to prevent
that statically by accepting only `Float` and `Double`
3. Consumers of the API then have no guarantees that a specific
`Encoder` supports the type that they need. Did the encoder remember to
support `UInt64` values? Similarly, `Encoder`s and `Decoder`s don’t
know what types they need to be considering. Am I supposed to handle
`UInt8` differently from `Int16`? With a list of concrete types, this
becomes immediately clear — both consumers and writers of `Encoder`s
have a clear contract.
Slava
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution