While experimenting with context parameter and bac...
# functional
j
While experimenting with context parameter and backing fields, I noticed that this works
Copy code
context(some: String)
val test: () -> Int
    get() = { some.toIntOrNull() ?: 0 }
And this seems to be ok for the compiler, it doesn’t complain
Copy code
val test: context(String) () -> Int = { /*some.toIntOrNull() ?:*/ 0 }
But the problem is that I can’t name the context parameter, I get this error “Named context parameters in function types are unsupported. Use syntax ‘context(Type)’ instead.” Is there a way to access the string from the lambda without naming it?
I know at that point I could just use partial application like
Copy code
fun test(some: String): () -> Int = { some.toIntOrNull() ?: 0 }
But I was not expecting the compiler to be ok with a “non-usable” context parameter
y
This is a general "problem" with any contextual lambda. That's why the stdlib also includes the
contextOf
function. In your example, it can be used like:
Copy code
val test: context(String) () -> Int = { contextOf<String>().toIntOrNull() ?: 0 }
j
aha I see, I did not know about
contextOf<String>()
, thanks!
Do you think the explicit backing field feature from 2.3 could help?
Copy code
context(some: String)
val test: () -> Int = { some.toIntOrNull() ?: 0 }
This gives “Property with context parameters cannot be initialized because it has no backing field”.
y
I don't see how that's meant to help. Do you want this?
Copy code
context(some: String)
val test: () -> Int get() = { some.toIntOrNull() ?: 0 }
This means that
some
is eagerly bound when you call
test
, but the returned value is still a lambda (a no-arg one)
j
Yes, I wondered if there would be a way to be able to declare it like so