why can't a `filter` smart cast ? ```connectors.f...
# announcements
t
why can't a
filter
smart cast ?
Copy code
connectors.filter { it is ServerConnector }.map { it as ServerConnector } // why is map needed here?
maybe there's a better solution for this?
d
In this case you can use
filterIsInstance<ServerConnector>
.
s
What if the lambda to filter is not a ‘constant’ lambda like
{ it is ServerConnector ]
, but a lambda-val or lambda-var…. The compiler cannot guarantee type safety. Ah… @diesieben07 already posted the answer 🙂
t
but in this case it clearly is. shouldn't it be able to recognize that?
@diesieben07 thank you !
s
The
filter
is defined to return the same type as its source type, something like this `fun <T> List<T>.filter(pred: (T) -> Boolean) : List<T>`; the compiler, looking at the signature of
filter
, can’t know that
T
will be same exact type (upper and lower bound) of all items.
g
Compiler doesn't analyse such complex expressions like this to know exactly how function filter works
t
thanks guys, i get that it doesn't, but i feel like it COULD check if the expression is a simple
a is b
and cast accordingly
i might be totally wrong though
a
g
But expression is not a is b, you also calling function filter on each invocation, so compiler should know how this function works together with your expression in lambda. Of course it's possible to write some kind intrinsic for this stdlib function, but than it will not work for third party code, again it's not something that impossible, but more what is not supported for now, some similar cases also supported by contracts, maybe contracts API may be somehow extended for such case, but it's just my guess
s
Even with Contracts, this will be tricky to do, i guess (how would you be able to examine the implementation of filter’s
predicate: (T) -> Boolean
parameter. Even when inlined, that would be tricky. And since there is a
filterIsInstance
function, it may not be worth the trouble… :)
g
Yes, I completely agree with you, I never had real use cases that are not covered by filterIsInstance (which is even more idiomatic imo), just some thoughts how it may be implemented in theory
s
mapNotNull works for me for this kind of filters more often than not. Simply return null if it doesn't match.
👍 1
k
I've created https://youtrack.jetbrains.com/issue/KT-30501 to improve the situation with some inspections
👍 3