Hey guys :wave: I'm trying context parameters, but...
# getting-started
r
Hey guys 👋 I'm trying context parameters, but failing in this case:
Copy code
fun bar(
    lambda: context(String) () -> Unit
) {
    with("") {
        lambda()
    }
}

fun foo() {
    bar {
        this // error
    }
}
Am I missing something? Is this not supposed to give me a string? I am not able to get the context parameter of the lambda in any way. If I try
bar { str ->
then "str" here is also an error 🤔
j
this
is no longer the correct syntax to access context receivers, you should now use
implicit<...>()
. See the KEEP: https://github.com/Kotlin/KEEP/blob/context-parameters/proposals/context-parameters.md#standard-library-support
r
I don't have this std library function 🤔 I'm applying kmp plugin with version 2.2.0, so it should also automatically add standard library dependency for that same version, right?
And also, shouldn't I be able to just call methods on String type directly? Maybe string is confusing here, but this next example:
Copy code
interface Logger {
    fun logme(msg: String)
}

fun bar(
    lambda: context(Logger) () -> Unit,
) {
    val logger = object : Logger {
        override fun logme(msg: String) = println(msg)
    }
    with(logger) {
        lambda()
    }
}

fun foo() {
    bar {
        logme("asd")
    }
}
I would expect logme to work, no? 🤔
j
Ah maybe the
implicit
function wasn't implemented 🤔
> I would expect logme to work, no? 🤔 No, you would need to refer to the parameter, which is not acccessible in the lambda.
logme
is defined with
Logger
as receiver. If you define another
logme
function with context parameter, it would work:
Copy code
context(logger: Logger)
fun logme(msg: String) = logger.logme(msg)
In general you should use context parameters to forward the context implicitly, but when you reach the final place where you actually use the context parameter, you need to refer to it by name. This is the major difference with the original context receivers proposal
👍 1
y
I thought the function was called
contextOf
? I can see it in Kotlin 2.2 projects
r
I see now, thanks @Joffrey
This means that if I want my function to enable users to just call `logme`I need to create a kind of wrapper function that calls the original one. This one would then need to be imported as well. It's a little annoying, but I guess it works 😛 Should probably read the KEEP more thoroughly to understand why they did it like this.
And this "annoyance" is only for this use case of the lambda with context parameter, since it is forcedly unnamed, so users have to use
implicit()
. For named params case, I think it's fine to just use the name 🙂