If I have an interfacez: ```interface Renderer { ...
# compose
e
If I have an interfacez:
Copy code
interface Renderer {
  fun render()
}

interface ComposeRenderer : Renderer {
   @Composable override fun render()
 }
will the compose mechanics work correctly if I call
render
polymorphically?
Copy code
class MyActivity : AppCompatActivity {
  private val renderer: Renderer = object : ComposableRenderer ...
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent { renderer.render() }
  }
}
a
As long as you also specify
@Composable
in your interface because
@Composable
changes the signature of the function.
e
In this case the value of `renderer`is inlined, so it's easy to see that it's an instance of
ComposableRenderer
. What about a case where the compiler can't deterministically see that it's a
ComposableRenderer
?
a
Composable functions are just standard functions with some extra parameters. They don't break the rules of Java/Kotlin including polymorphism.
e
Don't those extra parameters have to be added to the call site? How would the compiler know to add them?
a
The compiler plugin takes care of transforming the signatures of composable functions/lambdas and the invocation of them. I don't think there's much doc on these (as they are implementation details that may change from time to time) but if you are interested you can always read the source or check the byte code.
e
I was mostly asking rhetorically, as it's really just a restating of my question. When the compiler runs, it sees this as a call to
Renderer.render
which is not marked as composable. It has no idea that the actual Renderer implementation is
ComposableRenderer
, so I'd imagine that it wouldn't transform the signature. My question is then essentially, is there any way the compiler can infer that this actually is a composable call, and if not, I just want to confirm that the composable function wouldn't work.
a
That is exactly why it works only if you also specify 
@Composable
 in your interface.
h
Copy code
interface ComposeRenderer : @Composable () -> Unit
In theory, this should work too, but I never tried it out.
e
The problem is I need
Renderer
and
ComposeRenderer
to stay as declared above.
z
Does that even compile? I’d be surprised if it does, because composable functions have an entirely different signature than non-composable ones, so as far as the compiler is concerned that override isn't even valid. It’s like suspend functions: you can’t override a non-suspend function with a suspend function, or call a non-suspend function and expect it to suspend.
You can’t call a composable function from a non-composable function because the compiler needs to pass in some extra arguments and if the caller is not composable then it doesn’t know where to get those extra values.