[1] http://www.cis.upenn.edu/~bcpierce/papers/lti-toplas.pdf
[1] http://www.cis.upenn.edu/~bcpierce/papers/lti-toplas.pdf
Bidirectional propagation of type information allows the types of parameters of anonymous functions to be inferred. When an anonymous function appears as an argument to another function, the expected domain type is used as the expected type for the anonymous abstraction, allowing the type annotations on its parameters to be omitted. A similar, but even simpler, technique infers type annotations on local variable bindings.
From this I gather it means syntactically bidirectional. (But I don't understand this really, so someone should correct me :P)
Gamma |- e => t
Given Gamma (the environment) and e, you want to derive the type t (bog standard type inference).The other direction also holds:
Gamma |- e <= t
Now we want to ensure that e conforms to type t.Consider for example, a function:
func foo(a) b
and an expression that we know the type of already: e <= a
Therefore we can say when we apply `foo` onto `e`, we'll yield something of type `b`In effect, you perform 2 passes: forwards inference, and then backwards inference.
p/s: I'm not actually a PL person. This is from my casual reading, so my understanding is highly probably very wrong
https://people.mpi-sws.org/~joshua/bitype.pdf
edit: but it’s incomplete: it never gets around to discussing subtyping and thus helping justify its existence. I think the main point is that due to subtyping and other complexities, we may not be able to synthesize the type of an expression just by looking at it, but if its type has been determined by other constraints, we can still check that that type is valid for the expression.