Which is the most appropriate way to convert: ```v...
# getting-started
m
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
I don’t see actual difference, probably wildcard is better, it shorter and doesn’t require additional type information
e
I would leave it as a
{ }
lambda
g
Yes, also wanted to say this, it’s more clear imo, but question was “appropriate way to convert to a function reference”
m
@ephemient is that primarily because the type is generic?
e
primarily because the lambda is clearer even in non-generic cases
m
@ephemient so would you never use references?
g
I like references, but it usually more readable only for single param functions, not with functions with receiver
e
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
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
one, explicit type to know which it is and if something change in the future you don't be affected
s
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
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
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
that is true, we have just decided that we prefer to always do
::
whenever possible