Skip to content
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

Align Flow.single and Flow.singleOrNull implementation with standard library #2289

Closed
qwwdfsad opened this issue Oct 7, 2020 · 0 comments
Closed

Comments

@qwwdfsad
Copy link
Member

qwwdfsad commented Oct 7, 2020

Background

Historically, Flow.single and Flow.singleOrNull implementations were different from the corresponding Collection/Sequence operators.
It was done this way mostly by accident and creates an inconvenient inconsistency with the standard library, with all the chances to eventually become a coroutines "gotcha".

Inconsistent behaviour

  • singleOrNull operator throws an exception if the target Flow contains more than one element. Its standard library counterpart returns null.
  • single throws IllegalStateException when the target flow contains more than one or zero elements. Its standard library counterpart throws IllegalArgumentException.

Proposed change

The proposal is to make Flow.single and Flow.singleOrNull consistent with the standard library via breaking change in 1.4.0 versions. No migrations will be provided for this change.

Impact of the change

This is a breaking change. User-defined code may rely on the current behaviour and additional effort is required to migrate to Kotlin 1.4.
Both singleOrNull and single are typically used when it's known that the flow contains exactly one element and it's unlikely that IllegalStateException was caught around its usages.
For that, either exception type should be replaced with IllegalArgumentException or first operator can be used instead.

Possible alternatives

  • Do nothing and leave the behaviour as is. While it will preserve compatibility, undesired behaviour won't get fixed and eventually will become carved in stone without any chances to fix it. Even without it, 1.4 release will contain breaking changes in Flow-related operators (Breaking: Rethink atomicity of certain low-level primitives #1813), so it won't really prevent potentially seamless migration to the 1.4.
  • Deprecate single and singleOrNull and introduce new operators instead. It will make public API even bigger and less approachable while creating inconsistency and API gap with Kotlin standard library.
@qwwdfsad qwwdfsad self-assigned this Oct 7, 2020
recheej pushed a commit to recheej/kotlinx.coroutines that referenced this issue Dec 28, 2020
* Allow nullable types in Flow.firstOrNull
* Allow nullable types in Flow.singleOrNull
* Align Flow.single and Flow.singleOrNull with Kotlin standard library

Fixes Kotlin#2229
Fixes Kotlin#2289

Co-authored-by: Nicklas Ansman Giertz <nicklas@ansman.se>
recheej pushed a commit to recheej/kotlinx.coroutines that referenced this issue Dec 28, 2020
* Allow nullable types in Flow.firstOrNull
* Allow nullable types in Flow.singleOrNull
* Align Flow.single and Flow.singleOrNull with Kotlin standard library

Fixes Kotlin#2229
Fixes Kotlin#2289

Co-authored-by: Nicklas Ansman Giertz <nicklas@ansman.se>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant