template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u)
{
return t + u;
}
C++ is notoriously hard to parse. Consider the "most vexing parse", or the fact that refactoring tools for C++ are always flakier than their Java / C# / Go equivalents, or the fact that https://cdecl.org/ exists. New languages in the "expressive, high performance" niche cannot continue to be held back by C++ syntax.In rust, we have additional reasons, and that’s because it’s not
let name: type = expression;
It’s let pattern: type = expression;
Patterns offer more power than simple variable declarations. The names may not correspond 1-1 with the type, because you can create multiple names by destructuring more complex typesBtw the function syntax is:
fn foo(x: u16, y: u16) -> u32
If it were more C++ like it'd be: u32 foo(u16 x, u16 y)
Which is less keystrokes if anything.Haskell, Visual Basic, Scala, F#, Go, (Rust), Kotlin, TypeScript, Swift.
Even c++ allows you to put return types on the right. Why? Because putting the types on the right allows return type deduction. I think it's better to have a single syntax (all types on the right) rather than 2 syntaxes like c++ has.
https://medium.com/@elizarov/types-are-moving-to-the-right-2...
u32 foo(u16 x, u16 y)
auto foo(u16 x, u16 y) -> u32
IIRC there are contexts where the former does not work and the latter is required, which I believe means that ML-style function headers are strictly more powerful in C++ than the original C-style function headers.They should have done what java did. Copy C++ syntax, only change it when needed. I've ported over java code where 2/3 of lines are nearly identical.
The async debacle is a great example of this. They settled on weird syntax instead of doing what every other language does, because of some holier than thou acedemic snobbery. If every other language does it that way, it would have worked fine in rust.
> because of some holier than thou acedemic snobbery
The async syntax was one of the most widely discussed issues in Rust development, and ergonomics concerns were key in what eventually was chosen. It's very misleading to describe it as your comment does.
Re: parent comment, the Rust programming language book (free online) has a very nice section describing OOP-like patterns in Rust - as it turns out, the "good parts" of OOP are very nicely supported, and in a far simpler, more orthogonal way than what you get in C++. This means fewer dark corners in the language and something far easier to work with overall. Just because it may be different from what we did back in the 1990s, doesn't make it wrong!
However, I went through the book recently and I'm quite annoyed that much of the syntax differs needlessly from C like languages. It massively increases the cognitive overhead for someone coming from Java, C++, C#, C-like language world.
Rust is a systems language, it doesn't even have a runtime. 90%+ system level work is done in C-like languages. Rust syntax differs in countless pointless ways. I'm not saying it's wrong, it's just different in ways that don't matter from all other popular systems languages. Which is dumb.
Things like "fn" instead of "function" and async syntax make Rust difficult to adopt by the target user base. Why fn? Is saving 6 characters worth confusing everyone?
And it decreases the cognitive overhead for someone coming from Python, Ruby, Go, heck even Haskell or Ocaml. "Cognitive overhead" over a simpler, more elegant syntax (and I think I've made the case that Rust typing syntax is simpler once you move beyond trivial cases!) is a temporary issue anyway - you get used to it very quickly. What I find quite puzzling here is the particular issue you're complaining about, wrt. the C/C++ type declarations. You actually like having to write out things like "template" and "typename"? Now of course Rust syntax is rather C-like in other ways, but still!
Why should a new language inflict this horror on its users:
let i32 (*foobar)(i32, i32) = add;
When it can do this instead:
let foobar: fn(i32, i32) -> i32 = add;