Skip to content

Conversation

@lukellmann
Copy link
Contributor

@lukellmann lukellmann commented Apr 7, 2022

The type parameter T of DeserializationStrategy only appears in an out position, namely as the return type of deserialize().
It can therefore be annotated with out to increase API flexibility compared to DeserializationStrategy being invariant.
E.g. a function taking DeserializationStrategy<Number> would now also accept an object of type DeserializationStrategy<Int>.

This would also result in DeserializationStrategy being more similar to the symmetric SerializationStrategy interface which is already contravariant at declaration-site (interface SerializationStrategy<in T>), SerializationStrategy is a consumer, DeserializationStrategy a producer.

This change is

  • binary backwards compatible: generics are erased at runtime
  • source backwards compatible: previously specified out projections (use-site covariance) will only report a warning about a redundant projection

Please tell me when there is a reason why this shouldn't be changed or wasn't changed before, maybe I'm missing something.

@qwwdfsad qwwdfsad requested a review from sandwwraith April 7, 2022 09:49
@sandwwraith
Copy link
Member

Hi! I'm terribly sorry this PR was stale for this long; it completely fell out of my sight :(

I've dug through our initial design notes and haven't found any mentions regarding DeserializationStrategy variance — it seems that it was indeed simply just forgotten about, so there shouldn't be any problems adding it.

Given that the next release is likely going to be 1.5.0, now seems to be an excellent time to introduce this change. Can you please rebase your PR on the latest dev and check that it's still running?

The type parameter T of DeserializationStrategy only appears in an out
position, namely as the return type of deserialize().
It can therefore be annotated with out to increase API flexibility
compared to DeserializationStrategy being invariant.
E.g. a function taking DeserializationStrategy<Number> will now also
accept an object of type DeserializationStrategy<Int>.

This also results in DeserializationStrategy being more similar to the
symmetric SerializationStrategy interface which is already contravariant
at declaration-site (interface SerializationStrategy<in T>),
SerializationStrategy is a consumer, DeserializationStrategy a producer.

This change is
* binary backwards compatible: generics are erased at runtime
* source backwards compatible: previously specified out projections
  (use-site covariance) will only report a warning about a redundant
  projection
@lukellmann lukellmann force-pushed the covariant-deserialization-strategy branch from 038baec to a887620 Compare October 25, 2022 13:02
@lukellmann
Copy link
Contributor Author

lukellmann commented Oct 25, 2022

Hi! I'm terribly sorry this PR was stale for this long; it completely fell out of my sight :(

No problem :)

Given that the next release is likely going to be 1.5.0, now seems to be an excellent time to introduce this change. Can you please rebase your PR on the latest dev and check that it's still running?

Rebase is done 👍

Edit: I forgot to write this, but build is also passing locally

Copy link
Member

@sandwwraith sandwwraith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the change is relatively small, I don't have any objections. Thank you!

@sandwwraith sandwwraith merged commit 95d5b4f into Kotlin:dev Oct 26, 2022
@lukellmann lukellmann deleted the covariant-deserialization-strategy branch October 26, 2022 12:17
fred01 pushed a commit to fred01/kotlinx.serialization that referenced this pull request Nov 24, 2022
The type parameter T of DeserializationStrategy only appears in an out
position, namely as the return type of deserialize().
It can therefore be annotated with `out` to increase API flexibility
compared to DeserializationStrategy being invariant.
E.g. a function taking DeserializationStrategy<Number> will now also
accept an object of type DeserializationStrategy<Int>.

This also results in DeserializationStrategy being more similar to the
symmetric SerializationStrategy interface which is already contravariant
at declaration-site (interface SerializationStrategy<in T>):
SerializationStrategy is a consumer, and DeserializationStrategy is a producer.

This change is
* binary backward compatible: generics are erased at runtime
* source backward compatible: previously specified out projections
  (use-site covariance) will only report a warning about a redundant
  projection
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants