With context parameters, how would one access a pa...
# language-evolution
a
With context parameters, how would one access a parameter if there are multiple parameters of the same type in a lambda?
Copy code
fun foo(content: context(String, String) () -> Unit) {
    content("", "")
}

fun test() {
    foo {
        // Does not work: Multiple potential context arguments for 'String' in scope.
        implicit<String>()
    }
}
y
You're not meant to do that lol! There isn't really a way to get that to work, and ideally this would produce an error
a
I have no use case for it, but it feels like it needs to be an error possibly. But it would work fine outside of a lambda
y
Note that, outside of the lambda, it'd be very hard to call it with 2 different strings, maybe even impossible.
a
Sounds like a challenge to me
y
With reflection, anything is possible! I was also thinking a function reference, but it wouldn't actually work because the context parameters are resolved and filled out eagerly I believe, so you can't obtain a reference that has context parameters
a
Feels like until it’s figured out, parameter types should be unique
a
in this case you'll always get an ambiguity error for the resolution about uniqueness of parameter types: this cannot be imposed because of generics. A function of type
context(A, B) () -> Unit
for generic
A
and
B
makes sense in general. If we were to prohibit
context(String, String) () -> Unit
we would need to prohibit the generic one too (since it can be instantiated to
A = B = String
). Since we think the case of several generic distinct parameters is useful in general, we've decided to allow this (and the String,String case as a consequence), and move the "check" about whether it makes sense to the use site (that is, to the moment you try to fetch one of those context parameters)
💯 1
y
Couldn't we have a weaker check where it errors if any 2 context parameters are exactly identical? (And recursively does this for type arguments too just by having the exact same structure, no inheritance checks or anything).
a
we thought about having a warning whenever one of the types is a subtype (or equal to) the other. However, we decided against it because: • you'll actually get an error at the moment you need to resolve to one of them, so it makes no sense to have an additional warning • it's unclear how to treat generic types to guarantee that this check is done for every function at the end of the day, if you have context parameters very soon you're going to pass them somewhere else, and then you'll get the error. So why introduce some kind of heuristic of when things may go wrong on top of that error?
thank you color 2