Thread
#language-evolution
    e

    edrd

    7 months ago
    [not sure this is the right channel so let me know if there's a better place] I'm trying context receivers and tried to write an alternative "scoping" function but it didn't work:
    class Logging {
      val logger = java.util.logging.Logger.getLogger("test")
    }
    
    context(Logging)
    fun hello() {
      <http://logger.info|logger.info>("Hello")
    }
    
    fun <C, R> within(ctx: C, call: context(C) () -> R): R = call(ctx)
    
    fun main() {
      within(Logging()) {
        hello() // Error: No required context receiver found: Cxt { context(Logging) public fun hello(): kotlin.Unit defined [...]
      }
    }
    Is this supposed to be this way or it's just something not yet implemented in the prototype version?
    Changing
    within
    to use a standard receiver instead of a context receiver works, though.
    fun <C, R> within(ctx: C, call: C.() -> R): R = call(ctx)
    However I wanted to try lambdas with multiple receivers so to implement
    with
    functions for more than one receiver.
    Oliver.O

    Oliver.O

    7 months ago
    Works for me:
    class Logger {
        fun info(message: String) {
            println("INFO: $message")
        }
    }
    
    class Logging {
        val logger = Logger()
    }
    
    context(Logging)
    fun hello() {
        <http://logger.info|logger.info>("Hello")
    }
    
    fun <R> within(ctx: Logging, call: context(Logging) () -> R): R = call(ctx)
    
    fun main() {
        with(Logging()) {
            hello()
        }
    
        within(Logging()) {
            hello() // Error: No required context receiver found: Cxt { context(Logging) public fun hello(): kotlin.Unit defined [...]
        }
    }
    The above seems to happen if context receivers are not enabled for the compiler. Could you try this
    build.gradle.kts
    ?
    @file:Suppress("UNUSED_VARIABLE")
    
    plugins {
        kotlin("multiplatform") version "1.6.20-M1"
        application
    }
    
    repositories {
        mavenCentral()
    }
    
    kotlin {
        jvm {
            compilations.all {
                kotlinOptions {
                    jvmTarget = "1.8"
                    freeCompilerArgs += listOf("-Xcontext-receivers")
                }
            }
            withJava()
        }
        sourceSets {
            val jvmMain by getting
            val jvmTest by getting
        }
    }
    
    application {
        mainClass.set("MainKt")
    }
    h

    Hanno

    7 months ago
    I tried sth very similar but with two context parameters and it worked when i moved the lambda into a local variable and provided the type explicitly. So it works, also autocompletion in the lambda and so on, but not with an inline lambda, thats why i think its a bug.
    Oliver.O

    Oliver.O

    7 months ago
    I had overlooked that I had removed the first type parameter from
    within
    . As soon as I re-introduce it (
    C
    ), the error reappears. So yes, seems to be a bug.
    Anastasia Shadrina

    Anastasia Shadrina

    7 months ago
    Thanks for the report. I created the issue, looking into it.