Dear all, I would like to use lambda with context...
# getting-started
b
Dear all, I would like to use lambda with contexts. The following code does not work, as it complains that the block has no context specified:
Copy code
data class JdbcScope(val jdbc: Connection)
data class LoggerScope(val logger: Logger)

fun main() {
    runWithDbAndLogger {
        demoBlock()
    }
}

context(JdbcScope, LoggerScope)
fun demoBlock() {
    // do some stuff
}

fun runWithDbAndLogger(block: ()->Unit) {
    val jdbcScope = TODO("define here some connection")
    val loggerScope = TODO("define here your logger")

    with (jdbcScope) {
        with (loggerScope) {
            block()
        }
    }
}
This does not work:
Copy code
context(JdbcScope, LoggerScope)
fun runWithDbAndLogger(block: ()->Unit)
And that also does not work:
Copy code
fun runWithDbAndLogger(context(JdbcScope, LoggerScope) block: ()->Unit)
What would be the correct syntax do to it?
s
I think the context receivers are supposed to go after the parameter name, at the start of the function type:
Copy code
block: context(...) () -> Unit
I haven't checked it but I'm basing that on what's in the KEEP
y
Your code should look like:
Copy code
data class JdbcScope(val jdbc: Connection)
data class LoggerScope(val logger: Logger)

fun main() {
    runWithDbAndLogger {
        demoBlock()
    }
}

context(JdbcScope, LoggerScope)
fun demoBlock() {
    // do some stuff
}

fun runWithDbAndLogger(block: context(JdbcScope, LoggerScope) () -> Unit) {
    val jdbcScope: JdbcScope = TODO("define here some connection")
    val loggerScope: LoggerScope = TODO("define here your logger")

    block(jdbcScope, loggerScope) // sadly, we have to use this syntax for now
}
b
Great that works. Thanks a lot. @Sam and @Youssef Shoaib [MOD] And now an additional question: What if the block does not return Unit but a generic R? I could not find out where to put R or R: Any.
y
It works just like a normal lambda type:
Copy code
block: context(...) () -> R
👍 1