And that was a good decision. If it were too far from the C++ syntax, I would not have learned it, because as a mostly C++ guy at the time, some similarities with C++ helped me keep interest in Rust. Also, I was unable to parse Haskell's "type parameters as function applications" syntax, which was purely confusing. The Rust syntax is an abomination, that's true, but it is a necessary evil.
It's more like this,
Thing<A> becomes Thing A
Thing<A, B> becomes Thing A B
Thing<A, B, C> becomes Thing A B C
The parens only appears when you want to further nest types
And.. okay, I reckon that the Haskell syntax for types would be unfamiliar. But, at least, it's not as cluttered
let x = Foo::new();
x.bar();
Foo::bar(x);The syntax of type application and function application is already different in rust: F<A, B> vs f(a, b).
Type application even has default and named parameters! F<X = A, Y = B> and F<A> if B has a default.
I just think this particular type-level syntax is very noisy, specially because types in Rust tend to be very nested.
Things<Like<This, That>, That> -- as in C++
Instead of a more legible (and very familiar to Rust authors)
Things (Like This That) That -- as in Haskell
Inherited from C++, we had also :: for namespacing (while a dot . could be perfectly be used for that), and tons of other stuff like <> for scoping generics.
Without some of that we could have:
Perhaps it looks a little better? It looks for me, at least.For doing better than that we could drop C-like syntax perhaps?
The trouble is that languages have a weirdness budget - there's a finite amount of novel stuff a language can have until it becomes too weird for mainstream programmers. So language designers have to pick their weird features carefully. Spending it all in novel syntax is unwise.
I think that at the time the Rust pull was safety for low level code and, as Rust was targeted to replace some C++ components, following C++ syntax was seen as a good idea.