Conversation

I am just surprised it takes that long in Swift, as it is not that expensive in C# - and this was one of my original concerns when writing the C# compiler in C# that turned out to be unwarranted, it never shows up.
1
7
C#'s type inference is entirely bottom-up, which probably contains most of the problem. The combination of bidirectional inference with unrestrained overloading is what leads to Swift's issues
4
19
I don’t really understand what bidirectional inference and unrestrained overloading mean. I am guessing the former is probably close to the trial-and-error requirement that C# has for lambda methods which is indeed very slow. The latter I don’t know enough.
2
2
In Swift, sub expressions can pick up type information from context, like: x<T>() -> T int() -> Int float() -> Float let a: Array = [(x(), int()), (float(), x())] // infers Array<Float, Int> and context also influences overloading
2
16
We need a clearer way to distinguish these two: 1. “bidi typechecker”: has separate checking & inference judgements, vs. generating & solving constraints 2. “bidi typechecker”: has upward deduction & downward inference of type info, vs. monodirectional-only (‘var’, ‘auto’)
1
1
Hmm... can't yet tell if we're thinking of it the same way. I view bidi, being "downward propagation of expected type", and unification, as independent features which can either or both be added onto an upward-propagating base (though of course they interact!).
1
I used to get really confused by some people using it in an exclusive sense (only expected type propagation, aka "local type inference"), and others an inclusive one (does have expected type propagation, doesn't matter what else it does or doesn't). Is this also your distinction?
1
I'm honestly not an expert, so I'm probably mixing up terms. The contrast I see is between bottom-up type systems like C/C++/C#, where every term has to have a type decided before the outer expression can, vs. ones where type information can flow freely "up" and "down" the tree
1
2
The terms are mixed up even among experts. “Bidirectional typechecking” is a way of organising a type *system*, dividing typing rules into “check” (Ctx, Term, Type) → Bool vs. “infer” (Ctx, Term) → Maybe Type, which naturally leads to organising the type *checker* that way…
2
3