question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Flow.firstOrNull should allow nullable types

See original GitHub issue

Flow.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:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
zach-klippensteincommented, Sep 10, 2020

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 (or singleOrNull) 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.

1reaction
ansmancommented, Sep 10, 2020

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found