Youssef Shoaib [MOD]
03/19/2022, 6:15 PMcontext(A) fun <A> given(): A = this@A
sadly the type needs to be specified whenever given
is used because it doesn't infer the type parameter from usage (it instead latches onto the closest receiver).Gavin Ray
03/19/2022, 6:33 PMYoussef Shoaib [MOD]
03/19/2022, 6:39 PMcontext(List<Int>, List<String>, Long)
fun doSomething() {
repeat(given<Long>() {
println(given<List<Int>>().last())
println(given<List<String>>().first())
}
}
Youssef Shoaib [MOD]
03/19/2022, 6:39 PMthis@List
notation, which doesn't accomodate generics. This is inspired by given
which used to be a feature in Arrow Meta that did almost the same thingraulraja
03/19/2022, 6:52 PM@Context annotation class Config
@Context annotation class Persistence
@Config fun a(): A = ...
@Persistence fun b(): B = ...
context(A, B)
fun foo() {}
materialize<@Config A, @Persistence B>.foo()
That is DI for context receivers in addition to namespaced isolated injection based on type resolution. No source codegen just compiler substitutions in FIR and IR. If FIR works as expected IDEa will tell you when you are missing provider and other resolution errors when materializing.Gavin Ray
03/19/2022, 7:10 PMBecause the recommended way is to use theOhhh, got it that makes perfect sense. I've used Scala 3's `given`/`using` so I'm a bit familiar with the context receivers concept but I didn't know it had this limitation -- thanks for sharing!notation, which doesn't accomodate generics.this@List
Gavin Ray
03/19/2022, 7:10 PMThat is DI for context receivers in addition to namespaced isolated injection based on type resolution. No source codegen just compiler substitutions in FIR and IR.That looks fantastic! One of the biggest uses I've had for
given
in Scala 3 was easy DI, since you can just declare singleton objects and then inject them with (using config: Config)
How do the annotations work here exactly?raulraja
03/19/2022, 9:45 PMraulraja
03/19/2022, 9:47 PMinternal
making them of higher priority in candidate resolution