[variance question] I'm building a DSL that repres...
# getting-started
c
[variance question] I'm building a DSL that represents "expressions". Expressions are typed using two criteria: • Their return value (same as the Kotlin type of an expression) • The "context" in which they are available. This brings a design like:
Copy code
interface Expression<Context : Any, out Result>
Expressions can be combined together using the typical operators;
Copy code
val first: Expression<A, Int> = …
val second: Expression<A, Int> = …
val sum: Expression<A, Int> = first + second
The "context" must be the same for both operands for the operation to make sense. So far, this is simple to do. The difficulty is the existence of a special class of values that simply ignores context. That is, if put in an operation where the other operand has a context
x
, this special value behaves as if its context was also
x
, and thus the result expression should have context
x
. Essentially, this special value is "contextless", a kind of joker. What is the correct variance to represent this special value?
Said otherwise, the context rule "flows" opposite to the type rule; • The return type of two operands decides the return type of an expression, • The context of the expected result of an expression dictates the acceptable contexts of the operands
d
So, is it basically the "Any" context?
Copy code
interface Expression<in Context : Any, out Result>

operator fun <Context : Any, Result> Expression<Context, Result>.plus(other: Expression<Context, Result>)
    : Expression<Context, Result> =  TODO()

data class Contextless<T>(val value: T) : Expression<Any, T>

fun <C:Any> foo(exp: Expression<C, Int>) {
    val sum: Expression<C, Int> = exp + Contextless(1)
}
Does this work for your case?
1
c
Yep, that was the solution, thanks!
I was confused but yeah,
in Context : Any
was the solution