Wouldn't you like to use TopLevelEncoder and TopLevelDecoder without importing Combine? I know I would!
TopLevelEncoder and TopLevelDecoder are protocols that describe the encoders and decoders engineers use to kick off encoding/decoding an object graph (rather than the local any Encoder and any Decoder values passed to encode(to:) and init(from:) respectively). These protocols are particularly useful for library code that wants to encode and decode values but doesn't really need to care much about the format used.
The protocols are currently declared in Apple's Combine framework (and aren't declared at all on non-Apple platforms), but they probably belong in the standard library next to Encodable and Decodable.
Currently presumably the conformances Foundation.JSONEncoder: TopLevelEncoder and Foundation.JSONDecoder: TopLevelDecoder live in Combine; should there be a matching SF- proposal to move these to Foundation?
One issue I've had with these protocols is the concrete Input and Output types. Ideally it'd be possible to specify that TopLevelDecoder.Input could be anything that can vend bytes, and TopLevelEncoder.Output could be anything that can consume bytes. Given the difficulty in making that change though, and the presumed-imminence of "new codable", perhaps there's no point in attempting a fix?
I'd have to defer to the Foundation team here, but I would imagine they would move, yes.
Foundation has a ContiguousBytes protocol that serves (part of) this purpose. I would personally like to see it move to the standard library too, but that's beyond the scope of this proposal.
I think it could be moved to FoundationEssentials, but given that Codable will be refactored and optimized for Embedded Swift, I would vote against moving TopLevelEncoder to stdlib.
To support generic decoding in streams. It is odd that the original Codable proposal didn't cover that use case, but I think that limitation was intentional, as they didn't want to lock down the interface.
I don't believe that is a given. There are certainly discussions around alternative serialization APIs (and JSON in particular has been discussed at length) but I haven't seen any discussion of a refactoring of Codable for Embedded Swift (nor any indication that such a refactoring would impact Swift-proper.)
But let's say Codable is getting such a makeover. Embedded Swift thrives on protocols and generics (it just dislikes existentials.) So wouldn't it benefit from TopLevelEnc/Decoder?
While the new world may replace old Codable, perhaps we can view this pitch more like a cleanup than anything else really -- those types living in Combine are pretty out of place, and it would make sense to move them. I've definitely encountered this problem in the past when I was working more with Codable.
Since there's existing systems using Codable, I'd support this cleanup, even if we're moving towards the "2.0" future with new APIs.
I’m in favor of this proposal as well. These protocols are useful concepts, and I don’t think we should leave these protocols in Combine for all time, even with the “New Codable” APIs coming.
@itaiferber might have some more context about the historical decision for settling this API in Combine instead of lowering it to the stdlib when it was introduced.
Hey, let's keep this chain going! IIRC, @Philippe_Hausler/@Michael_J_LeHew_Jr would actually know definitively, but as far as I'm aware, the decision came down to Combine needing the concept of generic encoders/decoders for streams sooner rather than later, along with the fact that there wasn't enough/any precedented need for these types to be worth pitching for inclusion in the Standard Library. From what I remember, the thought was "if this really turns out to be beneficial then we can pitch lowering it", so to that end, if there's enough of a need for these types, I think they can be worth lowering.
(Take my recollection with a grain of salt; it's been a few years.)
Without having formed an opinion on the overarching question, if such a protocol is to be sunk into the standard library, is now the time to adopt primary associated types and typed throws (and maybe noncopyable and nonescapable if it makes sense)? It seems it should be feasible to do so now, and likely not so feasible later:
Those changes could be a future direction. This proposal is specifically concerned with migrating the protocols as-is to maintain binary compatibility on Apple platforms while also exposing them elsewhere for the first time.
I’m raising the point because I’m concerned about that: could it even be a future direction?
If it could be done in future, a fortiori it is better off as a current direction because all of these concerns about compatibility are amplified when a protocol is sunk into the standard library, and with wider adoption. Ergo, it is worth doing now. If it could not be done in future, then it is certainly worth doing now.
All roads (to me) point to doing it now. Put another way: my opinion is unformed as to whether we should sink these protocols in some form into the standard library now, but I am quite certain that we should not do so “as-is” without giving due consideration to adoption of modern features.
As we are fond of saying, "future direction" doesn't mean "it's gonna happen". It absolutely could be a future direction: we added Failure to AsyncSequence well after it originally shipped, as an example.
It would be a breaking change on Darwin if we didn't add compiler magic to handle it however, so we'd need to consider whether it's worth the engineering cost. I don't think it is, though the stdlib and/or compiler folks might disagree.