- Notifications
You must be signed in to change notification settings - Fork 105
Description
As Andrzej pointed out recently in a draft paper on the Library Evolution reflector, the JSON conversion heuristics currently prioritize checking sequence-like before checking optional-like. This means that any optional-like types that are ranges will serialize like a sequence ([42] and [] instead of 42 and null) and fail to deserialize (due to lack of push_back or insert), and, more importantly, an optional type that later adopts a range interface will break any users that use Boost.JSON (without even knowing if any such users exist).
There are multiple other languages whose optional type is a sequence, so it's not far-fetched to suggest that a C++ one might exist also (regardless of whether std::optional ends up being one or not).
There are at least two ways to preemptively address this issue that I can think of (though there are probably more solutions):
- Prioritize checking optional-like over sequence-like.
- Have sequence-like just assert against optional-like (on the premise that you meet two criteria we don't know what you mean, so we're not going to guess - this would make (de)serialization ill-formed, but ill-formed is better than well-formed and wrong)
I think an optional<pair<string, T>> that is a range is also very nearly map-like, only rejected by emplace probably not returning tuple-like. But it hypothetically could also (maybe you return the previous state as a bool?), so some care needs to be taken there too.
I think a similar question might be asked of described classes that are also ranges. How should those be serialized, as objects or as arrays?