https://kotlinlang.org logo
#compose
Title
# compose
h

Harold Scissors

06/27/2023, 9:45 PM
Why is it possible to call a
@Composable
function from a
.map{}
but not
.flatMap{}
?
s

Stylianos Gakis

06/27/2023, 9:50 PM
Doesn’t sound right. Are you sure that is what’s happening, and not just that you are not fulfilling the needs of the flatmap lambda which is to return an Iterable? While map can just return Unit (the generic gets inferred as Unit) which is also what your composables return anyway
h

Harold Scissors

06/27/2023, 10:10 PM
Our situation is little different from using the Compose UI. This is related to the Compose Runtime where we have a compose function returning
data class
. Oddly enough if we I just write this extension function and use this instead of
Map.flatMap
it works
Copy code
public inline fun <K, V, R> Map<out K, V>.composableFlatMap(transform: (Map.Entry<K, V>) -> Iterable<R>): List<R> {
    return flatMapTo(ArrayList<R>(), transform)
}
s

Stylianos Gakis

06/27/2023, 10:17 PM
Aha, well I don’t know what you mean by “doesn’t work” then, is it a compile time error, is it red in the IDE? While this function doesn’t do that? Super odd if so.
h

Harold Scissors

06/27/2023, 10:18 PM
Its it's a lint error, yes.
s

Stylianos Gakis

06/27/2023, 10:21 PM
What does it say? 😅
h

Harold Scissors

06/27/2023, 10:24 PM
image.png
And the function is flagged
@Composable
l

Loney Chou

06/28/2023, 1:18 AM
Could you show us more context of your code?
h

Harold Scissors

06/28/2023, 3:17 AM
I'll try to write up an example that creates the same issue
a

Alex Vanyo

06/28/2023, 6:33 PM
The built-in
.flatMap
should work the same way as
.map
.
inline fun
are pretty neat in that they allow calling back and forth from colored functions like
suspend
and
@Composable
without needing to be either themselves
j

John Petitto

06/28/2023, 6:53 PM
Ya, that's what I would expect too. I just wrote this code snippet to confirm that you cannot invoke a
@Composable
from
flatMap
but funny enough you can wrap
flatMap
and it works!
Copy code
@Composable
fun SimpleComposable() {}

inline fun <T, R> Iterable<T>.flatMapWrapper(transform: (T) -> Iterable<R>): List<R> = flatMap(transform)

@Composable
fun Run() {
  listOf(1, 2, 3)
    .map { SimpleComposable() } // works
    .flatMap { listOf(SimpleComposable()) } // compilation error
    .flatMapWrapper { listOf(SimpleComposable()) } // works
}
h

Harold Scissors

06/29/2023, 12:26 AM
@Alex Vanyo Just wanted to see if you saw the same error in the code snippet posted by John? It is doing the same error I mentioned.
a

Alex Vanyo

06/29/2023, 6:21 PM
Yep I can repro with that, it definitely looks like there is a bug somewhere there. Can you report one with that repro?
j
l

Loney Chou

06/30/2023, 8:16 AM
That's weird.
flatMap
is definitely
inline
.
h

Harold Scissors

07/03/2023, 5:09 PM
@Alex Vanyo Sorry to ping you, but do you have a link to the official repo to report that to?
a

Alex Vanyo

07/03/2023, 5:41 PM
I believe it was already reported in the message above, thanks for following up!