https://kotlinlang.org logo
#getting-started
Title
# getting-started
m

Mark

03/01/2022, 2:30 AM
Which is the most appropriate way to convert:
Copy code
val foos: List<Foo> = ...
foos.takeIf { it.isNotEmpty() }
to a function reference 1️⃣
foos.takeIf(List<Foo>::isNotEmpty)
2️⃣
foos.takeIf(List<*>::isNotEmpty)
3️⃣
foos.takeIf(Collection<Foo>::isNotEmpty)
4️⃣
foos.takeIf(Collection<*>::isNotEmpty)
5️⃣ leave it as a lambda
1️⃣ 2
3️⃣ 1
4️⃣ 1
5️⃣ 10
g

gildor

03/01/2022, 2:46 AM
I don’t see actual difference, probably wildcard is better, it shorter and doesn’t require additional type information
e

ephemient

03/01/2022, 3:00 AM
I would leave it as a
{ }
lambda
g

gildor

03/01/2022, 3:02 AM
Yes, also wanted to say this, it’s more clear imo, but question was “appropriate way to convert to a function reference”
m

Mark

03/01/2022, 3:04 AM
@ephemient is that primarily because the type is generic?
e

ephemient

03/01/2022, 3:05 AM
primarily because the lambda is clearer even in non-generic cases
m

Mark

03/01/2022, 3:05 AM
@ephemient so would you never use references?
g

gildor

03/01/2022, 3:06 AM
I like references, but it usually more readable only for single param functions, not with functions with receiver
e

ephemient

03/01/2022, 3:08 AM
I almost never use references. you have to go through type resolution to determine which overload is in use, or the reference might fail due to ambiguity, whereas the lambda is exactly what you see
👍 1
1
m

Mark

03/01/2022, 3:08 AM
I often use:
takeUnless(String::isBlank)
because it just looks cleaner than using a lambda, but I wish I could do something like
takeUnless(it::isBlank)
or
takeUnless(ITEM::isBlank)
or even with some compiler magic
takeUnless.isBlank()
j

Javier

03/01/2022, 7:50 AM
one, explicit type to know which it is and if something change in the future you don't be affected
s

Sam

03/01/2022, 9:20 AM
Unrelated to the reference vs lambda question (where I agree with what's already been said), but another option for the original example is
foos.ifEmpty { null }
m

Michael de Kaste

03/01/2022, 12:57 PM
We at work use either 1 or 3 because of the more stricter implication on what it means to do such function. it also means we can stricter test on why and how we chose to do such functions. If we ever change class or signature, the test will break. This means you have to reevaluate if the changes were wanted
e

ephemient

03/01/2022, 4:01 PM
you can do that with a lambda too:
Copy code
foos.takeIf { it: List<Foo> -> it.isNotEmpty() }
but I think that's a poor way to do a compile-time type assertion. it would be clearer to
Copy code
val foos: List<Foo> = ...
in the first place
m

Michael de Kaste

03/01/2022, 4:17 PM
that is true, we have just decided that we prefer to always do
::
whenever possible
11 Views