Flow.firstOrNull should allow nullable types
See original GitHub issueFlow.firstOrNull
does not allow nullable types, presumably so that you can differentiate between the flow being empty or not. However, every other firstOrNull
function such as List.firstOrNull
does allow nullable types and I see no technical reason why the flow version should not allow nullable types.
This change would be binary compatible since the type argument’s nullability isn’t even reflected in the bytecode. It would also be source compatible since it only loosens the restrictions.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:3
- Comments:6 (6 by maintainers)
Top Results From Across the Web
Hmm why is Flow firstOrNull restricted to non nullable types ...
Hmm why is Flow firstOrNull restricted to non nullable types Feels like it d be useful even with flows with nullable types.
Read more >How to handle nullable types in generic class - Stack Overflow
This class uses a generic type. The type can also be a nullable type. When I call the consumer, the value can be...
Read more >Kotlin Flow Nullable Value - ADocLib
Allowing null to flow into an expression of some other type means any of those If you have a variable of type String...
Read more >single() and singleOrNull() - Klassbook - CommonsWare
If you call single() on a Flow , it will return the first object that the Flow ... singleOrNull() returns null if the...
Read more >An opinionated guide on how to make your Kotlin code fun to ...
To allow better maintainability and readability, we should instead ... What you ALWAYS want to avoid, is receiving a nullable type in a ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I strongly disagree that exceptions should be used to detect the empty case. In general, exceptions should not be used for control flow at all, they are expensive and should be used to represent only “exceptional” cases, as the name suggests (e.g. incorrect usage of an API).
I also disagree that using null to detect empty is purely hypothetical. I have also written lots of code (albeit with lists, not flows) that uses
firstOrNull
(orsingleOrNull
) in chains of calls with elvis operators where null at any point in the chain is used to represent something like “not found” and terminate the chain.Your example has some pretty specific concerns, eg that emitting a null at the wrong time could overwrite a previous value. That seems very specific to the use case of a data repository type of API. Also, your reason for not taking the simple approach of emitting null before closing is definitely hypothetical (somebody could one day change the code), and I don’t think it’s a good justification for not taking that approach: of course someone could change any code some day and break anything - code isn’t written in stone. One of the jobs of unit tests is to verify important, load-bearing behavior like that.
I think it makes sense for the stdlib to provide functions that err on the side of caution and safety and don’t expose ambiguities. Given the current stdlib function, it might not cover every possible use case but its returning null has a single meaning and it means the same thing in every codebase. You can easily write your own extension function that does what you want and keep the ambiguity scoped to your codebase, where you’re willing to accept the potential risk that comes with the ambiguity. However if the stdlib were to include the function you’re requesting, that ambiguity would be introduced into every kotlin codebase, and it would be much harder to just look at unfamiliar code and figure out if the null value is being used for both semantics, or was intended to only mean one thing and there’s a hidden bug. This is one of the major issues with Java APIs that Kotlin solves, it would be a real shame to go backwards.
I feel like being able to differentiate between an empty flow and a null value is a weaker use case then simply wanting the first element of a flow with a nullable type.
My use case is that I often have flows with a nullable type where I want to await the first element. For my purposes I don’t care if the item is null or the flow is empty.
You’ll still be able to differentiate between empty flows and null when using non nullable types and for nullable types you’ll simply have to use
first()
with a try catch.