-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Design: auto-folding Some(None) → None #32
Comments
could you talk more about how you end up with Optional<Optional> ? |
The rule is simple — do not use |
I thought about your case for some time and probably I can understand it (the description is a bit vague though, so I am speculating in any case). Also, Paco brought good points on Twitter, but seems like you weren’t satisfied. We had a thought some time ago that optional is essentially the same as nullable which introduces the weird dichotomy — when to use optional and when to use nullable? What I see in your description suggests that you are trying to use optional as nullable replacement. Honestly saying this is not what Koptional was designed for — it is a solution for The suggested marshaling is pretty obvious. data class Data(val value: Optional<String>)
serialize(Data(Some("text")))
serialize(Data(None)) is { "value": "text" }
{ "value": null } data class Data(val value: Optional<Optional<String>>)
serialize(Data(Some(Some("text"))))
serialize(Data(Some(None))) is { "value": "Some(\"text\")" }
{ "value": "None" } If you want to be defensive you are free to introduce nesting checks. This however will not save you from bad understanding of JSON (and other formats) serialization and deserialization. What you are proposing is not good on two cases.
This is a slippery slope we had before with Java, just with JSON. Cross-language conversion is hard and we are fighting the lost battle here. We are surrounded by JVM walls with our shiny nullability conventions. And this returns me to the initial statement — avoid using |
Yeah it's hard to think when data class SomeContainer<T>(val field: Optional<T>, …) Where @ming13 your points are good and very similar to what I have on mind with one exception
It is not obvious (let's talk about JSON for now). With { "value": "text" }
{ "value": null } In your proposed schema (btw it's invalid JSON) you add Koptional specific metainformation to the JSON, which makes it incompatible with consumers that don't know about Koptional. { "value": "Some(\"text\")" }
{ "value": "None" } Actually would be this (or {
"value": {
"some": "actualValue"
}
}
{
"value": {
"none": null
}
}
What I'm trying to achieve with this proposal is transparent serialization/deserialization with Koptional including nested cases. So that we're still having this: { "value": "text" }
{ "value": null } It is already possible to write type adapter in this manner, however then you end up having different presentation in memory vs serialized as long as we treat inner To summarize, our philosophy in Koptional was that essentially I think it's possible to reach same consistency in serialization/deserialization or maybe not, let's figure it out! |
Its purpose is to be invalid. It is an indication of programming error, i. e. serializing something that wasn’t meant to be serialized. I. e. fallback to Do you want to introduce a Lint check instead for putting |
Well, that was my initial thought to throw exception (not Lint) if we detect that inner value is |
@weefbellington from our team at Lyft has been working on serializing/deserializing Koptional values in JSON and we've stuck for some time discussing following use case:
Optional<Optional<T>>
(and other levels of direct nesting).This use case is weird on its own, however Koptional does nothing to prevent it (neither does Arrow btw), so it's a valid state for Koptional 1.x.
Right now we've decided to serialize/deserialize without enhancing JSON with additional metadata, which results in following convention for JSON:
However, that creates difference between how we represent
Some(None)
in-memory vs JSON.With all that in mind, I'd like to raise a discussion about this and propose following changeset for Koptional 2.x:
Some
constructorSome(): Optional<T>
that would returnNone
forSome(None)
cc @ming13 @dmitry-novikov @nostra13 @AlecStrong @Egorand
The text was updated successfully, but these errors were encountered: