Good post though.
Good post though.
Almost everything that people think is ugly about Rust's syntax exists for very specific reasons. Most of the time, imo Rust made a good decision, and is just making something explicit.
Some things take time to get used to (e.g. if let), but for most people that's less an issue of syntax, and more an issue of not understanding a powerful feature (e.g. pattern matching deconstructions).
I understand pattern matching deconstructions, I have seen it in other languages. Funnily enough they were nowhere as ugly / noisy / complicated as Rust's is. Rust seems to have bolted on a lot of fancy shit that may be appealing to a lot of people and that is it.
In your link, the first one is fugly, the last one is fine. Maybe Rust just encourages ugly (i.e. complicated) code a bit too much.
And despite that I do use Rust when I want something simple to deploy/deliver, as handing over a binary that just runs is such a nice experience, and it's real easy to make fast. As long as I don't have to maintain in long-term, Rust is fine for what it is.
I don't know, it feels like you're just saying that you don't like it, missed the point of the post, and are not giving us anything concrete. Can you list a very clear example of how you'd improve the syntax?
Again, see the post: You can remove things, but you're losing explicitness or other things. If you want a language that's more implicit, this is fine. I don't.
The demand that I must design a better language to have valid criticism is absurd - I don't need to be a chef to know food tastes bad, do I? I'm a user of languages, not a language designer. My job is to evaluate whether Rust's syntax serves my needs, not to solve the PL design problems that led to it.
The syntax is noisy. That's not "missing the point" - that's the direct consequence of the design choices you're defending. If your argument is "the complexity is necessary for memory safety" fine, but don't pretend the cost doesn't exist or that pointing it out is invalid.
You're conflating "can identify a problem" with "must solve the problem". Those are different skills. I'm evaluating Rust as a user, not auditioning as a language designer.
You say "over-complicated". I disagree, my impression is that is mostly about as complicated as it needs to be to solve the problems it is trying to solve.
You do not have to know what programming language I prefer either[1]. Why would you?
[1] If you are curious, I have talked quite a lot about it, along with why I dislike Rust.
I really dislike them. Makes me wonder if you just got distracted and forgot to finish the function. Be explicit, don't make me have to spend time figuring it out.
The type of a variable and the return type of a function are the most important pieces of information regarding those, so they ought to be on the left. It also fits the data flow going right to left (i.e. how the '=' operator works). C's type declarations can get pretty gnarly, so there is definitely room for improvement there. I would say Java (and C#) got it as close to perfect as possible.
If you want to replace C/C++ you should make your language look as inviting as possible to users of the old one. I truly think this strange fetish for putting types on the right is what gives C programmers the ick when they see Rust for the first time and is hampering its adoption.
Each to their own, I guess.
let Coordinates(x, y) = get_coords();
But this is intended for "exhaustive patterns". If you can't express an exhaustive pattern, like with an Option, then you can use let ... else let Some((x, y)) = get_coords() else { return };
if let is just an extension of this "let pattern" system.Once you internalize how patterns work (and they really work everywhere) it all starts to really make sense and feels a lot cleaner.
It took me about 2 years to feel somewhat comfortable but I'd still run into code where someone decided to use their own set of unconventional favourite features, requiring me to learn yet-another-way to do the same thing I had seen done in other ways.
I just got tired of it, didn't feel more productive nor enlightened...
The insert function, for what it’s worth, has nonstandard formatting; the de facto standard rustfmt tool would use more newlines, making it clearer and less dense. The function also uses a couple of syntactic features like `if let`, which may seem unfamiliar at first but become second nature in a few days at most.
^* I don't particularly enjoy the Ruby-borrowed || either, particularly because Alt-7 is a terrible key combination to type, but oh well.
On the QWERTY keyboard, the pipe is near the enter key and easily typed.
(This is how we end up with German cars, isn't it?)
Exactly which syntax should every language be using then? Everyone will give you a different answer.
> Randomly chosen bolts to use left hand threads just because it suits their arbitrary whim
Claiming the syntax was chosen randomly on a whim is very much not true: https://matklad.github.io/2023/01/26/rusts-ugly-syntax.html
And there are times when it does make sense to use left-hand threads.
Just because someone looks at new syntax and doesn't immediately understand it doesn't mean that syntax doesn't exist for good reason.
Also, if your language's constructs and semantics don't exactly match those in other languages, then giving them the same syntax would be actively misleading, and therefore a design flaw.
Syntax is also only an issue for people who haven't taken the time to learn the language. If you haven't learned the language, then familiar syntax isn't going to help you anyway. You'll just think you understand something you don't.
But, like, even then, there's screw drive (JIS vs phillips vs pozidriv vs a ton more) to worry about with screws. (never mind the obvious aspects of diameter & length; and whatnot else I happen to not know about)
The significant thing I think is that such trivial impactless questions just do not exist for programming languages. Even like comment starting characters is a messy question - "//" nicely aligns with "/* */" using the slash char, but "#" is a char shorter and interpreted languages need to handle "#!" as a comment for shebangs anyways. And things only get more complicated from there.
And, unlike with physical things, it's trivial to work with non-standardized things in software. Not like you're gonna copy-paste arbitrary code from one language into another and just expect it's gonna work anyway (else we wouldn't have more than one language).
I also don't think syntax is even a problem worth worrying about. It takes very little time to become accustomed to a new syntax. It's the semantics that are hard to learn. Difficulty syntax can often be helpful when learning a new language, as it serves as a reminder that the semantics are different.
(defun fib (n)
(declare (type (Integer 0 100) n))
(the (Integer 0 *)
(if (< n 2)
n
(+ (fib (- n 1))
(fib (- n 2).)I actually find the Rust syntax very natural, more than C in some areas.
typedef takes the identifier at the end of the statement.
The asterisk is used to de-reference but used to denote a reference in types.
While loops may take the condition after the block.
Please, every time you see someone praise Rust (every other day), tell them the same as you have told me, just the opposite way around.
Guess what? They would blame Forth, Common Lisp, etc., yet I could tell them the same things I am being told about Rust.
The latter's baroque syntax is not provably good or necessary, but I'd call it the other end of a compromise for safety and expressiveness. And once you learn it, you've learned much of the language by default.
Not so with with the first two! The mental models involved in reasoning about a piece of code require much more cognition on the part of the programmer.
You strike me as someone who isn't really prepared to have an actual debate on technical matters, because all you have done is:
- manufacture some fictional strawman who is complaining about languages you like
- tell me I'm wrong without even bothering to get into why
- claim that I'm biased, when all I've done is explain my opinion that all three languages are challenging in different ways
See your statement: "Not so with with the first two! The mental models involved in reasoning about a piece of code require much more cognition on the part of the programmer.".
Your whole comment is about favoring Rust over those two because Rust is your beloved language.
Additionally, it is not up to me to teach you Forth nor Common Lisp.
Finally, you should read your own comment where you replace Rust with Common Lisp, for example, and Forth and Common Lisp with Rust. You may see what I was referring to.
In fact, let me do it for you:
> Rust is demanding, but they demand different things of the novice programmer than Common Lisp. The latter's baroque syntax is not provably good or necessary, but I'd call it the other end of a compromise for safety and expressiveness. And once you learn it, you've learned much of the language by default.
> Not so much with Rust! The mental models involved in reasoning about a piece of code require much more cognition on the part of the programmer.
See it yet?
Using Vec for arrays is also annoying, repeating the mistake from C++.
Neither Rust nor C++ uses vectors as array, they're distinct things.
An array is a fixed-size object, which never allocates and its elements thus always retain their memory address. In Rust they're `[T; N]`, in C++ `T[N]` or more recently `std::array<T, N>`.
A vector on the other hand is dynamically sized object, that may (re)allocate to accomodate new elements, and the address of their elements can change. In Rust they're `Vec<T>`; in C++ `std::vector<T>`.
Good luck if you want to get into the code of a library to understand what a function does. You have to go through 3 macros and 5 traits across 5 files. When it could have been just a couple function calls.
People don’t stop and think if they really need that trait or macro for five seconds, they just have to use it every time