7 ms·
Do they deliberately make Rust so difficult to read or is it an unfortunate consequence of its complexity?
by Vurdentium 1y ago
Do they deliberately make Rust so difficult to read or is it an unfortunate consequence of its complexity?
- maggit 1y agoIt's more a matter of your personal preference and previous exposure to different languages. The way Rust reads is one of its super strengths in my book. I also really enjoyed Standard ML in university, and Rust picks up some of that (via OCaml).
- juped 1y agoSomewhere in between. There actually is a level of demand for languages which are annoying to use; whether this is annoying syntax or annoying semantics isn't much of a distinction, they dovetail. But more than that, there's demand for ML clones (but with curly braces), and neither ML nor generic-curly-brace is the strongest foundation to build readability on, unfortunately.
- baq 1y agoRust is a low-level ML variant with curly braces syntactically.
- dontlaugh 1y agoIt’s just familiarity. I find it much easier to read than C++.
- survirtual 1y agoShort answer: It is difficult because you aren't familiar with it, and your brain is still wired for memory-unsafe or GCed languages. But it is actually easier to read than most other languages when you understand it and how to navigate it. When I first started learning Rust several years ago, I shared your viewpoint. With a heavy preference for C++ syntax, I thought Rust looked atrocious. Then I learned it. I got good with it. I got comfortable with it. I switched from VS Code based IDEs to vim, then to IDEs with vim bindings (trying Zed now). Now, Rust reads like a dream -- aside from lifetime specifiers, which I think could be much smarter than they are now. Anyway, it has superior pattern matching and code searching. snake_case is easier to navigate than camelCase or PascalCase. Keywords are short and easily recognizable. Branching logic is much, much easier to follow. Error handling is explicit and also easier to follow (and I started out really missing try-catch). Code gen with macros eliminates a lot of headaches. A 1st class package manager that is fast & can be easily inspected, that seamlessly integrates into the code...the list goes on. The point is, it is a paradigm shift that doesn't hide much of anything away. When you consider there is no GC and you are in full control of memory, that there are strict syntax and styling rules that make the global Rust codebase universally accessible, once you switch to it you find yourself wishing everything was written in Rust. That is why people using it want to rewrite everything, even well established packages. A Rust-only codebase is buttery smooth.
- jamincan 1y agoIn general, I find Rust very readable. The areas I do find I struggle are generics and lifetimes, and I don't think it's a feature of Rust syntax that makes me struggle and is instead the fact that people tend to use non-descriptive names for lifetimes or generics. It's hard to pick apart a trait that has four generics name T, U, V, and W, or lifetimes 'a, 'b, and 'c. Usually people will try to make it the first letter of something meaningful, but it is still much harder to parse. My own preference is to use more descriptive names except in trivial cases. Having the lifetime mirror a struct member name or a parameter name is really helpful for understanding them, in my opinion.
- tialaramex 1y agoYeah, I think it's non-obvious that you can name a lifetime 'frame not 'f - yes the compiler won't know you named it that because it's only supposed to live for one frame, but that's also true for your variable named timeout, Rust can see it's a Duration, so it has appropriate affordances, but it can't know you meant to call set_timeout(timeout) and not just store it somewhere. I have a backlog item to find Rust docs which use a concise lifetime name but could value a better one, however there aren't actually that many cases other than the scoped threads which do indeed name the scopes 'scope and 'env showing that we can give these meaningful names.
- weakfish 1y agoAlthough I disagree with your point made, I appreciate you taking the time to write a well-thought out reply.
- juped 1y agoPainfully realistic satire, but the end lays it on a bit too thick.
- timeon 1y agoWhich part in that link are you finding difficult to read? First example with `match` seems to me already more readable than `switch` statement with breaks.
- wruza 1y ago>Option<T> option >match option >if option.is_some() >Neither of these options is particularly appealing. There’s the answer. The new syntax is just particularly appealing. Does “if let some of x be assigned an option:” make better sense and sound greater than “match option, some of x:” and “if option is some:”?
- Defletter 1y agoIt's certainly cleaner, but my immediate thought when reading was "that's a compile error" because it looks like it's declaring a variable with a type mismatch. This is where, in other languages, the "case" keyword (or similar) comes in handy (eg: Dart's if-case syntax[1]), except Rust doesn't have that because of its headlong pursuit of 'conciseness'. - [1] https://github.com/dart-lang/language/issues/2181 https://github.com/dart-lang/language/issues/2181
- tialaramex 1y agoI think the fact you had to re-consider it shows you're not thinking in patterns. Rust is a language which always had pattern matching so in Rust it feels natural to, for example: while let Some(work) = inbox.pop() { /* ... */ } [edited: thanks HN, of course since this is code I don't need to escape the asterisks, unless I do]
- Defletter 1y ago> you're not thinking in patterns It's not that... well, it might be, but I use pattern matching fairly regularly in a number of languages. But Rust has hijacked the variable syntax and changed it beyond recognition: there's no matching operator being used; the same code does different things based on its surroundings: // This causes a compilation error let Some(work) = inbox.pop() // But putting it 1:1 within a while statement is fine? while let Some(work) = inbox.pop() { /* ... */ } Whereas, with Java's pattern matching: while (inbox.poll() instanceof final Work work) { /* ... */ } It borrows the variable declaration syntax too, which can be extracted fine without issue, but there's an operator being used to express that pattern matching is happening. Different languages have different uses, histories, and quirks, yes, and this is by no means to suggest that Java is a better language or that it doesn't have its own flaws. But Rust coopting of that syntax makes the language harder to learn and harder to comprehend at a glance, in my opinion. It seems to be like one of those situations where, once you learn it, it's fine, but that's my point.
- rowanG077 1y agoNo doubt there are some things that are hard to read in Rust. In the link posted everything seems very straightforward and should make sense if you know a c-like language.