Rust has type inference similar to Haskell: type information can flow "backwards". It is very different to Go and C++ where types of locals are 'inferred' from their initialiser, and nothing else.
E.g.
fn main() {
let mut v;
if true {
v = vec![];
v.push("foo");
}
}
is a valid Rust program: the compiler can infer that `v` must have type `Vec<&str>` based on how it is used. I don't think it's possible to syntactically write a Go program at all similar to this (a variable has to be either initialised or have a type), and the C++ equivalent (using `auto v;`) is rejected, as `auto` variables need an initialiser.
The C++ analogous, although not exactly the same, is to use a `make_vector` wrapper, like
template<typename...Args>
inline auto make_vector(Args&&...args) {
using T = typename std::common_type<Args...>::type;
return std::vector<T>{{std::forward<Args>(args)...}};
}
...
auto v = make_vector("asd", "dsa", std::string("asdsa"));
It will obviously not deduce types after the vector is declared, but it's as close as one gets to type deduction based on the vector's content.
There is one instance in C++ where information does flow backwards in a sense: disambiguating template overloads. For example,
using fn_type = std::vector<int>(&)(int&&,int&&,int&&);
auto v = static_cast<fn_type>(make_vector)(1, 2, 3);
In this case, the static_cast information flows "back" to the type deduction of `make_vector` to deduce what Args&& is. This is not very useful, just a curiosity.
Doesn't type inference stop at function boundaries, though? I'll grant you that idiomatic Haskell uses type annotations for function signatures (unlike idiomatic OCaml), but it is optional (which is convenient in a REPL).
E.g.
is a valid Rust program: the compiler can infer that `v` must have type `Vec<&str>` based on how it is used. I don't think it's possible to syntactically write a Go program at all similar to this (a variable has to be either initialised or have a type), and the C++ equivalent (using `auto v;`) is rejected, as `auto` variables need an initialiser.