# Why doesn't firstOf exist?

We have extensions functions:
`first`, `firstOrNull`, `firstNotNullOf`, `firstNotNullOfOrNull`
but not:
`firstOf`, `firstOfOrNull`

Why is that the case?

For example with my implementation of `firstOfOrNull` like:

``````inline fun <T, R> Iterable<T>.firstOfOrNull(
transform: (T) -> R,
predicate: (R) -> Boolean
): R? {
for (element in this) {
val result = transform(element)
if (predicate(result)) {
return result
}
}
return null
}
``````

Using it in an example situation, compared to doing the same with `firstOrNull` and `firstNotNullOfOrNull`:

``````val sortedValueList = listOf("1", "2", "3", "4", "5")
fun transformation(s: String) = s.toInt() * 10

listOf(
{ i: Int -> i > 25 },
{ i: Int -> i > 100 },
).forEach { predicate ->
listOf(
//0 firstOfOrNull
sortedValueList.firstOfOrNull(::transformation, predicate),

//1 firstOrNull (does 1 extra transformation compared to the other two)
sortedValueList.firstOrNull {
predicate(transformation(it))
}.let { it?.let { transformation(it) } },

//2 firstNotNullOfOrNull
sortedValueList.firstNotNullOfOrNull {
val t = transformation(it)
if (predicate(t)) t else null
}

).forEachIndexed { i, it -> println("\$i: \$it") }
}
``````

(Outputs)

``````0: 30
1: 30
2: 30
0: null
1: null
2: null
``````

I think there is a point in having the `firstOfOrNull` function as it is cleaner.

Or did I miss something?

Is it any different than `list.map(...).first(...)`?

(Kotlin 1.9.0)

``````public inline fun <T> Iterable<T>.firstOrNull(predicate: (T) -> Boolean): T? {
for (element in this) if (predicate(element)) return element
return null
}

@kotlin.internal.InlineOnly
public inline fun <T, R : Any> Iterable<T>.firstNotNullOfOrNull(transform: (T) -> R?): R? {
for (element in this) {
val result = transform(element)
if (result != null) {
return result
}
}
return null
}
``````

`first` functions would return after finding the first element

`list.map(...).first(...)` would perform mapping for all the entries, then find the first match

1 Like

Then: `asSequence().map { ... }.first { ... }`.

I see your point. I’m just not sure if it makes sense to duplicate all filtering operators like first, last, filter, takeWhile and many more just to provide lazy map+filter functionality. Not to mention combinations like e.g. flatMap+filter.

1 Like

Yeah but in that case it got me thinking why something so verbose like `firstNotNullOfOrNull` exists to begin with

1 Like

Isn’t this `find`? find - Kotlin Programming Language

1 Like

No way ahahahahahaha

Ah hold on `find` does not take transformation functions, no?

Found this

From a purely aesthetic position, functions that take multiple lambdas in Kotlin are kind of ugly imo; having the final lambda be outside the parentheses results in a nice look for Kotlin, but if you have multiple lambdas, then at least one has to be inside parentheses and it looks weird. For example:

``````listOf(1, 2, 3, 4, 5)
.firstOfOrNull({ it * 2}) { it > 5 }
``````

vs

``````listOf(1, 2, 3, 4, 5)
.map { it * 2 }
.firstOrNull { it > 5 }
``````

Plus as broot said, it’s really not that much extra code to transform your collection to a sequence and then do map + firstOrNull.

yeah I agree that the `({ ... })` block looks pretty bad

`lastNotNullOf` and `lastNotNullOfOrNull` also doesn’t exist when their “first” counterparts exists, there are consistency issues here

``````fun <T, R: Any> Iterable<T>.lastNotNullOfOrNull(transform: (T) -> R?): R? {
var last: R? = null
for (element in this) {
val result = transform(element)
if (result != null) {
last = result
}
}
return last
}
``````

but then similarly again, if this shouldn’t exist then why should its counterpart `firstNotNullOfOrNull` exist
I can’t help but to feel like there is something I am missing, something that I didn’t consider beside the readability or aesthetic issues

Now that I’ve looked at `firstNotNullOfOrNull` and `firstNotNullOf`, I think those are kind of weird functions to have… a simple `map` that returns a null followed by `filterNotNull` and then `firstOrNull` would work… I guess it’s a bit shorter, but it seems like a pretty niche use case to have a built-in language function for this. Maybe a lot of the Kotlin devs need it so they added it as a standard function? Or… I think Kotlin language features are often requested by the community, yeah? Maybe there’s a ticket for adding those standard functions, which would have explanations from people as to why they wanted those functions.

Which can be avoided by converting to a sequence:

``````list.asSequence().map(...).first(...)
``````

In fact I would rewrite your function as:

``````inline fun <T, R> Iterable<T>.firstOfOrNull(
transform: (T) -> R,
predicate: (R) -> Boolean
): R? =
asSequence().map(transform).firstOrNull(predicate)
``````

There is another alternative with firstNotNullOfOrNulll:

`````` inline fun <T, R> Iterable<T>.firstOfOrNull(
transform: (T) -> R,
predicate: (R) -> Boolean
): R? =
firstNotNullOfOrNull { transform(it).takeIf(predicate) }
``````

That is the nice thing about Kotlin, if you find such a function valuable, you can add it. It is not likely to make it in stdlib because there are other ways to do it and because they generally try to have only one lambda parameter in a function call as it is more readable.

1 Like