> My only gripe with Rust is that they should have taken a page out of Python's book in making a langugage syntax both stringent and beautiful.
I prefer Rust's syntax to whitespace-sensitive languages.
> I think syntax like fn foo(bar: int) -> string {}; is a step backwards. More glyphs, more arcane nomenclature, and I just get a ting of change for the sake of change or "I want to be a functional hipster".
No, Rust's type syntax is the way it is to avoid the lexer hack, which causes real problems in C++ (typename qualification, in particular).
> What is wrong with rettype name<templates>(argtype argname): ?
The lexer hack.
> Why are there so many damn macros when C++ is realizing having language features rather than preprocessor macros is a huge usability gain?
Rust macros are not preprocessor macros, not even close. Macros are language features.
What is the lexical hack in relation to the syntax I proposed?
I'm not arguing it, I'm just curious why Rust is using the prefix var pointer syntax when you are almost never supposed to use those in language.
I guess my point is more you could start from a clean unambiguous syntax (when is "rettype name<templates>(argtype argname):" ambiguous?) and rather than just verbatim copy C's glyphic syntax append vocabulary to the language to describe ill-used features.
One thing I have always considered a reasonable design choice going forward would be to start* with somethking akin to ptr(foo) rather than foo to denote dereferencing. In general I would like to see languages in this field start* with vocabulary and transition to glyphic grammar only on the most frequently used language features.
That would mean you could start with a language that does things like this:
int foo(5)
short bar(3)
long res(foo.plus(bar))
bar.equals(foo)
And then you could have just int, short, long etc classes that have operator overloads for =, +, etc and systemically avoid glyphic overload ambiguity because you are forced to handle that ambiguity in the operator descriptions.
With modern compilers (particularly LLVM) this could probably work very well, because the optimizers are so good even if you start defining your primitives in object notation and handing off really ugly bytecode that is treating everything as a non-dynamic object the backend llvm equivalent asembly generator will almost certainly be able to strip all the overhead out and return you back to optimized platform specific math operators onregister-sized words.
I'm not a language designer (obviously). I'm just a developer frustrated with how every language but Python is so much harder for my uncle to read (who is not a programmer) and thus makes me spend more brain energy deciphering it than if it were less verbose and more plaintext. And after writing a few of the Rust tutorials on the weekend a few months ago and giving a crack at writing a webrtc library for it I was really frustrated with how much extraneous glyphic grammar I had to learn and deal with in the language, since it seems so much worse than C++ from my perspective.
(Note that your comment is a bit difficult to read because Hacker News turns asterisks into italics.)
Putting the type name before the variable name can grossly complicate your tooling (the aforementioned lexer hack, https://en.m.wikipedia.org/wiki/The_lexer_hack ), which is part of the reason why tooling for C and C++ is so relatively rudimentary despite thirty years of time to address it.
There are also semantic difficulties that can arise from putting the type name before the variable name. For example, C++ recently added a return-type syntax that resembles what you see in Rust:
auto multiply (int x, int y) -> int; // this is valid C++
Furthermore, the `name: type` syntax is simplest solution when your language supports both patterns and type inference, as Rust does. IMO it also reads more nicely because when scanning code I care more about what a value's name is than its type (which may only be because Rust's type system is relatively strong, and I count on it to catch me if any types are out of place).
There's also the emerging historical trend: AFAICT, every language designed in the past ten years has put the type after the variable name. Rust, Go, Swift, TypeScript, Nim, Crystal, Pony... even Python 3 (https://www.python.org/dev/peps/pep-0484/). All the proposals that I've seen for optional types in Ruby and Javascript put the type after the name as well. And this syntax has roots in a much older language, ML, and is generally shared by ML's descendants (such as OCaml, and also possibly Rust).
For someone who uses Reddit and HN too much I sure can forget about markdown.
The function syntax C++ has seems more like a bandaid around the broken scoping rules inherited by C more than anything. If you were writing a replacement it seems like it would be one of your first considerations to make each statement scope limited to the scope of the declaration. I mean, that is what auto is effectively doing in C++ nowadays - you have to evaluate the whole statement to resolve what auto is supposed to be at compile time.
I would take consistency of using postfix typing as a sign there is legitimacy and simplicity in compiler design to do so, but I don't think the Python example is particularly fair, since it (and the C++ ->) are both extending a language that already had declaration syntax and thus the kind of glyphic overhead imposed by colons and arrows is less condemnable because they had to maintain backwards compatibility.
My gripe boils down to the difference between "August 5th" and "5th of August". The latter can convey the information in a more meaingful sense (you usually care about the day more than the month if you are using both) but it comes with a grammatical overhead "of" that, if were writing and reading a lot of dates of this form, would have a tangible impact on overall reading and writing efficiency. It would of course be minor - that is why its a gripe, and I still love Rust from what I've done with it - but it nags on you like it could have been done better.
And I also can understand the concept of name over type, but as someone who strongly favors static typing over dynamic after about five years of Python and three of C++, I think just conceptually "Canister Bob" is easier to parse than "Bob the canister". It is almost certainly just habit, but I justify my appreciation of the habit because it doesn't need to involve those damn conditional constructs (be they the, if, or a colon) that clutter up my reading and writing.
I prefer Rust's syntax to whitespace-sensitive languages.
> I think syntax like fn foo(bar: int) -> string {}; is a step backwards. More glyphs, more arcane nomenclature, and I just get a ting of change for the sake of change or "I want to be a functional hipster".
No, Rust's type syntax is the way it is to avoid the lexer hack, which causes real problems in C++ (typename qualification, in particular).
> What is wrong with rettype name<templates>(argtype argname): ?
The lexer hack.
> Why are there so many damn macros when C++ is realizing having language features rather than preprocessor macros is a huge usability gain?
Rust macros are not preprocessor macros, not even close. Macros are language features.