https://kotlinlang.org logo
#arrow
Title
# arrow
c

CLOVIS

03/15/2023, 10:45 AM
Sorry if this is off-topic, but a lot of people here have played with context receivers. If I write
Copy code
interface A
interface B

context(A, B)
fun foo() { … }
can I call it like this?
Copy code
class Context : A, B

with(Context()) {
    foo()
}
Said otherwise, can a single object satisfy multiple context receivers?
p

pakoito

03/15/2023, 10:47 AM
Yeah, AFAIK
c

CLOVIS

03/15/2023, 10:48 AM
That's great: it means we can use interface delegation to combine contexts
p

pakoito

03/15/2023, 10:49 AM
s

simon.vergauwen

03/15/2023, 10:50 AM
This technique is actually explicitly specified in the KEEP as a recommended pattern.
c

CLOVIS

03/15/2023, 10:51 AM
Context receivers are available on the playground? mind blown
The Kotlin team is always one step ahead, lol
c

carbaj0

03/15/2023, 10:52 AM
Screen Shot 2023-03-15 at 11.52.32.png
p

pakoito

03/15/2023, 11:03 AM
inb4 Context2, Context3, Context4…Context21 😄
until someone hits the “these two dependencies share an ancestor” diamond problem
c

CLOVIS

03/15/2023, 11:04 AM
The KEEP does say you're supposed to keep them to a minimum…
If anyone is interested, I'm creating a library based on Jetpack Compose and context receivers to declare compile-time dependencies between components and automatically inject them at runtime → #decouple
I'm going to (ab)use this knowledge :)
y

Youssef Shoaib [MOD]

03/15/2023, 11:22 AM
Btw, I believe this pattern is used within the FIR code to circumvent some of the current compilation issues with context classes (at least I presume that's why). I'll see if I can find an example of that.
After digging a bit I found at least the usage of
Fir2IrComponents
as a context receiver for utility functions, and then in the classes that contain those components, they're defined like:
Copy code
class CallAndReferenceGenerator(
    private val components: Fir2IrComponents,
    private val visitor: Fir2IrVisitor,
    private val conversionScope: Fir2IrConversionScope
) : Fir2IrComponents by components
I think there was a time where they were doing that pattern with multiple context-like classes and not just
Fir2IrComponents
, but searching the codebase now it seems that they have everything they need within that class and hence its the only context-like class I could find that's used with that delegation pattern
Turns out
Fir2IrComponents
was introduced in March 2020, way before context receivers were in the language, so it's likely that the usage of delegation there is an artifact of that time and there just hasn't been enough of a reason to change it to using a
context
receiver on the class
8 Views