To me this is an argument for why Go should not add type inference to function/method declarations. Go is like Rust (I guess, I haven’t used Rust) - type inference works for declaring a variable (or const) and generic type parameters but not for type declarations, methods, functions, etc. I was in the “more inference is always better” camp but now I’m thinking Go has the perfect level of inference. Except for function literals/lambdas. I really want go to infer the argument and return types when I’m passing a function literal/lambda to a function.
The thing about Rust’s type inference that seems wild to anyone who hasn’t seen Hindley-Milner/ML style type systems before is that it’s “bidirectional” (in quotes because that’s not a proper type theory term as far as I know). The type of the left-side of an assignment can determine the type (and behavior!) of the right side. For instance, this is ambiguous:
let foo = [("a", 1), ("b", 2)].into_iter().collect();
The expression creates an iterator over the (letter, number)
pairs, and collect()
stores the elements in a newly created container. But which container type? Here are two valid variants:
let foo: Vec<_> = [("a", 1), ("b", 2)].into_iter().collect();
This creates a vector with items ("a", 1)
and ("b", 2)
.
let foo: HashMap<_, _> = [("a", 1), ("b", 2)].into_iter().collect();
This creates a mapping where "a"
and "b"
are keys, and 1
and 2
are the corresponding values.
Playground link in case you’d like to mess with this concept: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=76f999f4db600415643b0c58c19c69b7