
Yeah, I think that works fine. Say you have the type signatures:
map : ∀(infer a : Type, infer b : Type) → (a → b) → List a → List b
make-adder : ∀(infer c: Type, a implements Plus) → c -> (c → c)
make-adder x = lambda (y: a) x + y
and you call:
map (make-adder 10) [1, 2, 3] // evaluates to [11, 12, 13]
First you infer c = Int because the argument 3 has type Int, then you infer a = Int, b = Int because (make-adder 10) has type Int -> Int. Note that we’re not doing general unification here: all of these inferences are always “type variables = concrete types”. You can never get a constraint of the form a = b like you do with unification.
More detail about how I imagine this all working:
- At every use site of a variable, that variable’s type is known.
- Therefore, arguments to lambdas and functions require type annotations. Unless, as the blog post suggests, there’s already an expected type for the lambda that comes from the context it’s placed in. (E.g. if you pass a lambda to a function, and that function requires it to have a fixed type (no type vars), you can omit the types of the arguments to the lambda.)
- The return value of a function or lambda can be inferred by type checking its body, though I think we’ve correctly settled as a community on the requirement that function return types must be annotated (though not lambda return types).
- Given all of the above, you can nearly always tell the type of an expression given only the types of the variables that appear in it. The exception is, as just mentioned, that if the context an expression is in requires it to have a certain type directly (nothing fancy like “it must have the same type as that other argument”), then that required type can be used to disambiguate otherwise ambiguous types (like a lambda not annotating the types of its arguments).
score 3 · canonical
u64 r = random_u64(); // uniform chance over [0..UINT64_MAX] T chosen = choices[r % 10];…technically. Though how likely are you to actually see the difference? The relative chances of picking
0..10are 1844674407370955162 for0..6and 1844674407370955161 for7..10. Suppose you instead panicked for the largest 6 possible results ofrandom_u64(), making the remaining distribution uniform. The chance of encountering that error is6/2^64 = 3*10^-19, which you’re realistically not going to hit. That’s getting to the point where you’re more likely to notice a cosmic ray bit flip than to encounter the distribution being off.score 1 · canonical