# singleOrNull - what's your expectation?

**URL:** <https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085>\
**Category:** Language Design\
**Created:** [March 24, 2019, 9:15pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085 "2019-03-24T21:15:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![alamothe](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@alamothe](https://discuss.kotlinlang.org/u/alamothe)\
**Post date:** [March 24, 2019, 9:15pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/1 "2019-03-24T21:15:17Z")

</div>

In Kotlin’s standard library, there are extension functions `single` and `singleOrNull` defined on `Iterable` or `List`:

```
public fun <T> List<T>.single(): T {
	// ...
}

public fun <T> List<T>.singleOrNull(): T? {
	// ...
}

```

While there is no argument what `single` should do if list is not size 1, I’m wondering about your expectations for `singleOrNull`?

1. `null` if list is empty, throw if size \> 1
2. `null` if list is empty, `null` if size \> 1

In my opinion, Kotlin’s standard library is one of the best if not the best designed library for a programming language out there 🥰, however this is one of a few places where it defied my expectations (which lead to a production disaster).

As a result, we had to ban it from our codebase (similarly for `use` which I wrote about in another topic).

Thoughts?

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [March 24, 2019, 9:25pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/2 "2019-03-24T21:25:37Z")

</div>

I would expect `singleOrNull` to return null if the list is empty or has more than one element. This is consistent with the other `xxxOrNull` functions in the standard library. They all return null in the case that their base version would throw.  
Also this is clearly stated in the documentation of the function so I don’t see the big problem.

* * *

Could you link me the post about `use`. I can’t remember it and I would like to know why you don’t like it. As far as I understand it, it works the same way as javas try with resource statement.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 25, 2019, 6:40am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/3 "2019-03-25T06:40:38Z")

</div>

A stdlib function that ends on “orNull” never throws an exception. It’s easy to remember that.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [March 25, 2019, 9:05am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/4 "2019-03-25T09:05:25Z")

</div>

> [@alamothe](#):
>
> Thoughts?

RTFM

---

<div class="post-metadata">

**Author:** ![alamothe](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@alamothe](https://discuss.kotlinlang.org/u/alamothe)\
**Post date:** [March 25, 2019, 8:42pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/5 "2019-03-25T20:42:30Z")

</div>

Perhaps I’m too much into coding defensively 🙂 If I expect a list to have 0 or 1 elements, then if it has two elements something is wrong, and I don’t want to treat that case as if the list was empty.

Consider I want to create a new user, and username should be unique. Then I query the database to find if the username exists. If I get two rows back, something is wrong, and I don’t want to proceed as if the username is not there at all (and create yet another one).

It is much harder to come up with a practical example where you want to treat 0 and \>1 elements the same.

I am not making a case it is not documented well. I am saying that it goes against expectation which can lead to, and more importantly, hide other bugs. And another point is that the current behavior has less utility.

A quick search through Kotlin’s github repo: [Search · singleornull · GitHub](https://github.com/JetBrains/kotlin/search?q=singleornull&unscoped_q=singleornull) supports my intuition. 90% of the time `singleOrNull` was used there, the caller actually doesn’t expect \>1 elements.

---

<div class="post-metadata">

**Author:** ![pdvrieze](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/pdvrieze/32/1882_2.png) [@pdvrieze](https://discuss.kotlinlang.org/u/pdvrieze)\
**Post date:** [March 26, 2019, 12:16pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/6 "2019-03-26T12:16:51Z")

</div>

It’s a hard one. It is easier to state what I don’t expect

- Throw an exception of there are no elements
- Return any of the elements if `size>1`
- Behave fundamentally different from `single()`
- Throw an exception (It is the exception free version after all)
- Duplicate `firstOrNull()`

Based upon those requirements the current behaviour is the only valid behaviour, but I do see how it is also confusing. The problem I see is that if the two abnormal cases (0 or \>1 elements) may need to be handled differently, in that case it is not possible to have a single function do so (unless it is higher order). In the case that more than 1 element is an error, there is only one thing to it, test that. Perhaps with an extension function that explicitly throws an exception when there are multiple elements.

---

<div class="post-metadata">

**Author:** ![amerharb](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/amerharb/32/4928_2.png) [@amerharb](https://discuss.kotlinlang.org/u/amerharb)\
**Post date:** [March 29, 2019, 12:48pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/7 "2019-03-29T12:48:23Z")

</div>

I would go for (2) to return null

my expectation whenever I see …OrNull that a null will be returned instead of exception

---

<div class="post-metadata">

**Author:** ![vbezhenar](https://avatars.discourse-cdn.com/v4/letter/v/35a633/32.png) [@vbezhenar](https://discuss.kotlinlang.org/u/vbezhenar)\
**Post date:** [March 30, 2019, 7:42am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/8 "2019-03-30T07:42:48Z")

</div>

I expect it to throw exception on list of size 2+ and return null on empty list.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 30, 2019, 8:17am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/9 "2019-03-30T08:17:45Z")

</div>

People who expect this probably think that “single or null” stands for “the collection is allowed to have a single or null elements”.

But that is not the meaning of “orNull”. In the stdlib “orNull” generally means, returns null instead of throwing an exception. Hence “singleOrNull” would stand for “the collection is allowed to have 1 element, otherwise null is returned.”

---

<div class="post-metadata">

**Author:** ![vbezhenar](https://avatars.discourse-cdn.com/v4/letter/v/35a633/32.png) [@vbezhenar](https://discuss.kotlinlang.org/u/vbezhenar)\
**Post date:** [March 30, 2019, 9:12am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/10 "2019-03-30T09:12:30Z")

</div>

> [@fatjoe79](#):
>
> People who expect this probably think that “single or null” stands for “the collection is allowed to have a single or null elements”.

Yes.

> [@fatjoe79](#):
>
> But that is not the meaning of “orNull”. In the stdlib “orNull” generally means, returns null instead of throwing an exception. Hence “singleOrNull” would stand for “the collection is allowed to have 1 element, otherwise null is returned.”

I can’t imagine the code where this treatment is useful. It’ll hide bugs. I prefer bugs to explode early.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 30, 2019, 9:19am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/11 "2019-03-30T09:19:22Z")

</div>

> [@vbezhenar](#):
>
> I can’t imagine the code where this treatment is usefulI. It’ll hide bugs. I prefer bugs to explode early.

Often this is accompanied with an Elvis operator that handles the erroneous case immediately.

Examples:

```
staff.filter{ it is Janitor }.singleOrNull() ?: throw IllegalStateException("Dedicated Janitor not found")

```

Or

```
staff.filter{ it is Janitor }.singleOrNull() ?: fallbackJanitor

```

---

<div class="post-metadata">

**Author:** ![vbezhenar](https://avatars.discourse-cdn.com/v4/letter/v/35a633/32.png) [@vbezhenar](https://discuss.kotlinlang.org/u/vbezhenar)\
**Post date:** [March 30, 2019, 9:32am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/12 "2019-03-30T09:32:14Z")

</div>

Again, I can’t imagine the code where it would be useful. Why do you want to handle only the case when there is a single Janitor and multiple Janitors is not an error? Sure, it’s possible, but in my experience it’s rare case. And I’m usually using similar function to query database by unique set of fields and I’m using it a lot. I’m expecting to get exactly one row if I’ve found it and zero rows if I didn’t find it. Multiple rows indicate corrupted database and I want to catch that ASAP. Treatment of multiple rows as `null` means that my business logic will be wrong.

---

<div class="post-metadata">

**Author:** ![vbezhenar](https://avatars.discourse-cdn.com/v4/letter/v/35a633/32.png) [@vbezhenar](https://discuss.kotlinlang.org/u/vbezhenar)\
**Post date:** [March 30, 2019, 9:45am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/14 "2019-03-30T09:45:11Z")

</div>

I understand your reasoning and may be I just need a different function, say `singleOrNullIfEmpty()`. Anyway my point was that I’m using a function which is named very similary both in Java and in Kotlin and it works exactly like this: null for empty result set; exception for multiple items. So to return to the original question, my natural expectation was exactly this meaning. I can see that different people might see it differently and Kotlin already sealed its meaning, so it’s better to stick with it, whether I like it or not.

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [March 30, 2019, 10:20am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/15 "2019-03-30T10:20:36Z")

</div>

I think the problem comes from the predefined meaning of `xxxOrNull` in the kotlin standard library. As many people have pointed out it means that every possible error case is handled by returning null.  
Therefor I think that the current implementation of `singleOrNull` is the right one for the kotlin standard library. That being said, I think I would have chosen the other option if I were just to implement `singleOrNull` without the context of the library.

I also agree that depending on the domain you would want to throw exceptions more aggressively in order to ensure that you catch invalid states of persistent data early. I like the idea of `singleOrNullIfEmpty()`. It’s maybe a bit verbose, but it clearly states what it does and wouldn’t conflict with the `orNull` functions in the std-lib.

---

<div class="post-metadata">

**Author:** ![alamothe](https://avatars.discourse-cdn.com/v4/letter/a/c4cdca/32.png) [@alamothe](https://discuss.kotlinlang.org/u/alamothe)\
**Post date:** [March 30, 2019, 12:35pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/16 "2019-03-30T12:35:33Z")

</div>

> [@vbezhenar](#):
>
> Sure, it’s possible, but in my experience it’s rare case. And I’m usually using similar function to query database by unique set of fields and I’m using it a lot. I’m expecting to get exactly one row if I’ve found it and zero rows if I didn’t find it. Multiple rows indicate corrupted database and I want to catch that ASAP. Treatment of multiple rows as `null` means that my business logic will be wrong.

Exactly!

We ended up with our own extension `zeroOrOne` so that it doesn’t get mixed up with Kotlin’s convention. Still I feel it’s a dangerous function to have in the Standard Library.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 30, 2019, 3:47pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/17 "2019-03-30T15:47:33Z")

</div>

What’s dangerous are APIs that return a collection for something than can have zero or 1 element. 😉

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [March 30, 2019, 4:49pm UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/18 "2019-03-30T16:49:31Z")

</div>

I looked it up in our project. One of the real world uses of this function in our project is this:

We have a website where the user can search for products by category. He can combine an arbitrary number of categories. Those are stored in a collection.

When there is only one category in the current search, we want to optimize the page for that category according to SEO best practices. If there is no category or more than one category, we don’t want to do this optimization.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [April 11, 2019, 8:31am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/19 "2019-04-11T08:31:00Z")

</div>

Just in this moment, I am using singleOrNull for another use case, that I am glad to share.

The products on our website can be filtered by region. For this purpose the user can enter an arbitrary region name. Many regions have similar names like for example “Frankfurt (Main)” and “Frankfurt (Oder)”.

We have a region-name-resolving service that returns a collection of region objects for an arbitrary region name input. When the input matches multiple regions (e.g. “frankfurt”) then the collection will contain more than 2 elements.

This collection of region objects will be used for filtering the current search. However, the search will be filtered only, if the entered region name was not ambiguous. This is the simplified code example:

```
val regions = resolveRegionName(regionName)
filters.region = regions.singleOrNull()
didYouMean.regions = regions.takeIf { size > 1 }

```

---

<div class="post-metadata">

**Author:** ![christophels](https://avatars.discourse-cdn.com/v4/letter/c/7feea3/32.png) [@christophels](https://discuss.kotlinlang.org/u/christophels)\
**Post date:** [April 16, 2019, 7:11am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/20 "2019-04-16T07:11:57Z")

</div>

For complex cases, may be you should consider a specific “Single” class as “Optional” in Java.

```
enum class Cardinality {
    NONE, SINGLE, MORE;
}
class Single<T>(val value : T?, val card : Cardinality, val tail : List<T>)

fun <T> List<T>.single(filter : (T) -> Boolean = { true} ) : Single<T> { ... }

```

this allowed you to treat all cases with specific needs while keeping functionnal programming style.

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [April 16, 2019, 10:56am UTC](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085/21 "2019-04-16T10:56:24Z")

</div>

Not sure this should be part of the standard library, but in any way, it should probably be implemented like this

```kotlin
sealed class OptionalList<T> { // I can't think of a good name
    class None
    class Single<T>(val vaule: T)
    class Multiple<T>(val list: List<T>)
}

```

That way it’s a bit more idiomatic.

[Next page](https://discuss.kotlinlang.org/t/singleornull-whats-your-expectation/12085.md?page=2)
