4 ms·
I agree that Rust can look pretty weird to an untrained developer when lifetimes get involved. But, in Rust's defence, I haven't seen any other language write d
by jeroenhd 2y ago
I agree that Rust can look pretty weird to an untrained developer when lifetimes get involved. But, in Rust's defence, I haven't seen any other language write down lifetimes more concisely.
The underscore could've been a name if the name mattered, which would be required in many languages. Rewriting it to <'something>) may help readability (but risks introducing bugs later by reusing `something`).
Many C-derived languages are full of symbol soup. A group like <?,?>[]) can happen all over Java, for instance. Many of these languages have mixes of * and & all over the place, C++ has . and -> for some reason, making for some pretty unreadable soup. The biggest additions I think Rust added to the mix was ' for lifetimes (a concept missing from most languages, unfortunately), ! for a macro call (macro invocations in many other languages aren't marked at all, leaving the dev to figure out if println is a method or a macro), and ? to bubble up errors. The last one could've been a keyword (like try in Zig) but I'm not sure if it makes the code much more readable that way.
If you know other programming languages, the symbols themselves fall into place quite quickly. I know what <'_> does in Rust for the same reason I know what <T, R> T does in Java, while a beginner or someone who hasn't learned past Java 6 may struggle to read the code. Out of all the hurdles a beginning Rust programmer will face, the symbols are probably your least concern.
As for books, the Rust book on the Rust website is kept up to date pretty well. There are books for programmers coming from various other languages as well.
The language itself hasn't changed much these past few years. The standard library gets extended with new features, but a book a few years old will teach you Rust just fine.
In many cases, changes to the language have been things like "the compiler no longer treats this as broken (because it isn't)" and "the compiler no longer requires you to write out this long definition because it can figure that stuff out itself". I'd recommend running a tool called "clippy" in your IDE or on the command line, if you can leverage a modern language feature for better legibility, clippy will usually suggest it.
- dietr1ch 2y ago> I agree that Rust can look pretty weird to an untrained developer when lifetimes get involved. But, in Rust's defence, I haven't seen any other language write down lifetimes more concisely. Can you do a lot better? I don't think so and it wouldn't help that much. The truth is that most of the time we want to rely on some inferred lifetime annotations, but will obviously need an escape hatch from time to time. Rust doesn't waste a lot of typing around the annotations, but if you were to improve Rust, you'd improve the implicit inference, not the syntax for being explicit.
- flohofwoe 2y ago> Can you do a lot better? I don't think so and it wouldn't help that much. I think Rust could do a lot better inferring lifetimes if the compiler would be allowed to peek into called function instead of stopping at the function signature - e.g. if it had a complete picture of the control flow of the entire code base (maybe be up to a point that manual lifetime annotations could be completely eliminated?). IMHO it's not unrealistic to treat the entire codebase as a single compilation unit, Zig does this for instance - it just doesn't do much so far with the additional information that could be gained.
- rcxdude 2y agoIt's a dangerous option: Rust already has long compile times, expanding the space it has to analyze would only increase that. Not to mention you'd be much more dependent on the implementation details of a given function, and it'd become very messy. The fact that lifetimes have a specifiable interface is probably one of the main things that makes Rust's approach work at all. Rust has similar rules about type inference (of which lifetimes are a subset) at the function level as well. I think this was a lesson learned the hard way by Haskell, which does allow whole-program type inference, and how programmers working in it quickly learned you really want to specify the types at the function level anyway
- flohofwoe 2y ago> Not to mention you'd be much more dependent on the implementation details of a given function Hmm, but wouldn't that already be the case since the manual lifetime annotation must match what the function actually does? E.g. I would expect compiler errors if the 'internal' lifetime details of a function no longer match its manual lifetime annotations (is it actually possible to create incorrect lifetime annoatations in Rust without the compiler noticing?) Higher compile times would be bad of course, but I wonder how much it would add in practice. It's a similar problem as LTO, just earlier in the compile process. E.g. maybe some time consuming tasks can be moved around instead of added on top.
- 2y ago
- dbdoskey 2y ago(not OP) I love rust, bu I just think that using ' for lifetime was a huge mistake, and using <> for templates (rather than something like []) was a medium mistake. There is something about how the brain is wired, that using ' for lifetime, just triggers the wrong immediate response to it. Something like this would look so much nicer IMHO [$_], compared to this <'_>.
- dralley 2y agoI completely disagree that [$_] looks nicer than <'_>.
- Klonoar 2y agoI cannot imagine using syntax that’s largely reserved across languages for array indexing for such a completely unrelated topic.
- mmoskal 2y agoThis comes from ML (as in SML or OCaml), where 'a reads "alpha" and is a type parameter.
- selfmodruntime 2y ago> using <> for templates (rather than something like []) was a medium mistake I never get this take. Array indexing is done with []. This would just confuse the hell out of me.
- estebank 2y agoIt has the benefit of making the parsing of numeric comparisons unambiguous and trivial to parse. You'd use a different syntax for array indexing.
- colonial 2y agore: try keyword in Rust - this is actually a thing on nightly, although instead of bubbling up errors directly, it creates a scope (within which ? is usable) that evaluates to a Result.
- kazinator 2y ago> Many C-derived languages are full of symbol soup. C is not full of symbol soup though. It is more full of symbol soup than Pascal or Modula 2, and back in the day when C was taking over other such languages, there were lots of complaints about C's syntax being like "line noise" and whatnot. Rust takes it to a whole new level though.
- johnisgood 2y agoYeah, I wonder what people are referring to when they say C is full of symbol soup. I mentioned it in my other comment that C is not, just like how Common Lisp is not due to the parentheses, its syntax is pretty simple.