Taking a wild guess here, but it sounds like you maybe referring to issues addressed by Non-Lexical Lifetimes (NLL)?
NLL are a part of Rust 2018 Edition.
Three complementary books are the best resources:
- The Official book: https://doc.rust-lang.org/book/
- The Rust By Example book : https://doc.rust-lang.org/rust-by-example/
- Programming Rust (O'Reilly) : https://www.amazon.com/Programming-Rust-Fast-Systems-Develop...
Edit: removed outdated behaviour of migration mode.
If that were true, then this example would fail to compile, since it fails with the old AST borrowck: https://play.rust-lang.org/?version=stable&mode=debug&editio...
You can completely take advantage of any NLL feature, you just might be able to write code that should be an error but is instead a warning if you hit an edge case (I think this would be considered a bug in one of the borrow checkers since NLL is supposed to allow anything that the old borrow checker allows).
The transition mode is for Rust 2015 code.
In edition 2018, migration mode is turned on.
I learned myself about this today btw, after I saw this PR: https://github.com/rust-lang/rust/pull/58342
I think I was mistaken about one point though which is that migration mode is erroring if one of the two errors. IIRC migration mode was introduced that way but it seems to have been changed to be a bit more tolerant than AST borrowck.
Anyways, more NLL fun is to come, and it's to come to both editions.
Isn't it just “one mutator at a time”?
>Is there a K&R equivalent that an experienced programmer can get pick up to get productive with the language soon?
(Opinion incoming.) The Rust Book is great iff you are a complete beginner. If you are an experienced programmer, who knows his way around concepts like resource management and ownership, it's kind of a drag. Rust by Example is much better. The Nomicon is interesting, but it's mostly about unsafe.
Of course the big distinction is that Rust mandates it. There's lots of C code out there that happens to work fine with shared data structures that never collide in practice (or at least never collide under non-hostile input...) - see for instance every standard libc API that returns a pointer to a static buffer. Our codebase merely had a style guide, and lots of older code was less disciplined. Rust forces you to care up front about everything.
Here's my Rust advice for C and C++ programmers:
- Rust is a higher-level language than C. A C/C++ programmer could think of Rust as "C++ without most of the footguns and magic."
- Certain types of C/C++ code will translate very easily to Rust. For example, if your code mostly transforms bytes (or data structures) into other bytes (or data structures), then Rust will usually be fairly easy to learn. We could call this "mostly functional" C code, with only localized mutability, and with clear, hierarchical data structures. Examples: Most typical Unix CLI tools.
- Certain kinds of C and C++ will translate very badly to Rust. If you have a big web of mutable objects, all of which point to each other and update each other, then your first experience of Rust will probably be frustrating. Examples: doubly-linked lists, traditional GUIs, typical video games. You can do all these things in Rust, but you'll need to either re-architect them or use more advanced features. (See http://cglab.ca/~abeinges/blah/too-many-lists/book/ for doubly-linked lists, or https://kyren.github.io/2018/09/14/rustconf-talk.html for video games.)
- Async Rust is not ready for prime-time. We make limited use of async Rust at work. It's rock-solid and powerful, but it's missing critical ergonomic features and it demands a surprisingly high level of Rust knowledge. See https://areweasyncyet.rs/.
Honestly, if you're happy with C, there's no reason to switch to Rust. (Except, maybe, preventing exploits, if you worry about that.) If, however, you love certain parts of C++ and hate other parts of C++, then Rust might be worth a look. Anyway, that's my personal take. :-) Overall, I've been really enjoying Rust. It generates fast, reliable code and it fits the way I think.
1. Lots of little CLI tools, statically linked using https://github.com/emk/rust-musl-builder. These are fast, portable, easy to share, and easy to add to Docker containers. For a fun open source example, see https://github.com/faradayio/geochunk, which groups US zip codes into evenly-sized chunks.
2. Code where we need to handle all the corner cases very carefully. Rust's enum and match are wonderful for this. An older open source example would be https://github.com/faradayio/cage, which performed all sorts of fiddly transformations on docker-compose.yml files. (I need to massively overhaul this to work with https://kustomize.io/ someday.)
3. Code which moves around large amounts of data, and maybe processes some of it. This might involve REST APIs, AMQP queues, cloud buckets or databases. Sometimes we wind up writing a little extra glue code, but we're pretty happy overall.
This morning, I'm working on an unreleased open source command-line tool that moves large database tables between different local and cloud databases. This actually uses async Rust (specifically https://tokio.rs/blog/2018-08-async-await/), which is definitely bleeding edge. But this particular code benefits enormously from Tokio, so we're taking the plunge.
Overall, our Rust code is fast and reliable. I enjoy working on it, and my boss likes the fact that our Rust code tends to be very solid.
I also saw Kraken cryptocurrency exchange looking for Rust developers to help with transition, so it seems there is some work opportunities already in the field.
Rust is not for good c/c++ programmer.
It is for those who is not familiar with c/c++ but have some knowledge with functional programming.
As a C++ programmer, you can try golang instead of for productive
Then came what I thought should be a simple task; since my code was mostly recursive, I wanted to add and remove from a map containing the program's current binding state, so when the evaluator sees a 'let' block:
(let ((a 1) (b 2))
(+ a b))
As it turns out, Rust doesn't support using maps (or hash maps) in this way. You need to allocate and borrow them, and you can't borrow them in multiple places, so I couldn't have a function that checks whether something is bound, since I'm already borrowing the map in my evaluator function.
I was left asking: why can I do this in C (or another 'low level' language, passing the bindings as a pointer to array of a k-v struct that I simply swap with another and remember to free()) and do it in Python (or another 'high level' language like Haskell, creating the map anonymously when calling eval recursively), but not in Rust? The language seems to be somewhat focused on ideas of immutability, but I can't do the things that immutability lets me.
Other things seemed to get in the way too. Once you've 'match'ed a variable you can't actually deal with the thing you matched, because you've already borrowed it when you did the matching. In Haskell (case statement) this is no problem at all:
is_cons e =
case (car e) of
Nothing -> False
Just _ -> case (cdr e) of -- still matching on e
Nothing -> False
Just d -> ...
Your HashMap issues may have been solved by the Entry API.
Anyone can confirm ?
Currently, it's ready in the sense you can write robust, high-performance network code. It's still easier than in C or C++, but it's not noob-friendly compared to Node.js or Go yet.
Code based on Futures uses owned closures a lot, so you need to "get" ownership in order not to fight the compiler.
With the async/await syntax, the compiler will be able to relax some of the memory ownership restrictions, and you'll be able to write "normal" code instead of chains of callbacks.
Many people are waiting for async/await before saying “please come try this”, as it makes the enterprise far easier. We’re quite close!
I don't work there.
So you can write scalable servers using normal threads, normal callbacks, and async with the await! macro, but not the final async/await syntax because the community hasn’t even finished deciding what it is. Porting code between these approaches is also not particularily easy. I have seen example code for rust networking libraries that uses all of the different approaches, but mixing the different approaches is also difficult. So that’s probably why people say it’s not ready even though you can write code right now that will work just fine. The “final” way of writing it isn’t ready yet, and if you write one of the current forms, porting to the final form will be a pain.
For server-side stuff, what's not yet done is some infrastructure and improved ergonomics for writing asynchronous or non-blocking code. See https://areweasyncyet.rs/ . And then when the infrastructure is there, it'll take a while before the higher-level frameworks take advantage of it.
Rust has already shipped everything it needed to be production ready. We're just always excited for the next big thing. Two years ago it was incremental compilation, last year it was a new borrow checker, this year it's async/await, etc.
This will improve a lot once async/await stabilizes. It already works great in nightly if all of the libraries you want to use support it.
That actix you see appearing in most lists and mostly nearly top is written in Rust btw.
Fun fact- frameworks managed by microsoft dominate the space ;)
My only issue is how surprisingly weak Rust support is in my favourite editor. Rust seems to feel more popular than it is. Or maybe more people write Rust in a "no frills notepad" kind of way.
I've also just started writing Rust in the domain in which I write code, low level networking. I think I agree with Carmack in that it feels good. I can get hungup on syntax when learning a new language and I don't have that problem so much in Rust. I've been writing code in many different languages for close to 30 years and learning Rust feels mostly right. It feels like when I learned Python or LISP and I could guess at syntax and just get it right. As opposed to writing /bin/sh for over twenty years and still needing to constantly look up syntax :(
It doesn't feel like some languages I've learned in the past where everytime I investigate something I face-palm. It seems like the more I investigate it the right choices were made. Even when I'm frustrated with it because the compiler won't let me do something simple, I understand that maybe the bad habit I learned in C should end. Rust forces you to deal with things upfront that may become problems later. It's sometimes annoying when you want to just get shit done, but it's the 'right thing' to do.
It forced me to think harder about my code's structure. I think that's what I like about Rust too. Not being able to do anything means I have to be thoughtful.
Which also reminds me of how to be creative with games or writing or music: artificially limit yourself and you're forced to be more thoughtful.
If you need something more advanced, you can try clion from jetbrains with the intellij-rust plug-in.
I will need to try again. It's been six months.
I wish there was a trivial way to say to intellij, "steal all my config from vscode"
In the latest vscode release they now support multiline error messages so maybe the situation will improve.
Twitter: yes but have you tried my favorite language?!
Rust has gotten so much on HN lately that I think it may be time for me to make the switch.
Rust seems complete. The ownership paradigm is a bit difficult at first, but the compiler is good at pointing out exactly what the issue is.
Languages are products, either they change with times or they die.
Oh yes it is. Which means, a tool is an extension of oneself. We tend to identify ourselves with our tools, especially if they required extensive learning. The simplest tools (hammer) are easily replaced, but the more complex ones (my cello) are highly personal, and seldom swapped.
Programming languages fall on the complex end of the spectrum. They require learning, and to some extent, what you learn is what you are. Throwing away a programming language (and its ecosystem) is throwing away a good chunk of the knowledge you acquired there —a part of yourself. A new language needs to have one hell of an advantage to get significant adoption under those conditions.
And I didn't even talk about network effects…
Workmen also carry the burden of maintaining old (legacy) products.
No one would say no to a shiny new feature that makes tedious stuff easier.
However for my own use cases, my actual alternative is the newly founded love for low level programming support by Java and .NET designers. Mandatory GC is nice to have around, while only specific hotspots require a more machine friendly coding.
Changing between programming languages is a bit more complicated than exchanging tools in a belt.
I think the important question is, what will happen first:
(a) C++ gets better tooling around build systems and package management; or
(b) Rust libraries are written for all of the things that we care about?
Certainly in the HN bubble it feels like (b).
Sure it might not have as many IDEs, static analysers, debuggers and so on, but I'd easily take Rust's build system over C++'s tool ecosystem.
For cargo to win over cmake, it needs to finally support binary libraries.
For Rust to matter to .NET devs, it needs to support COM/UWP and mixed mode debugging on IDEs.
On Android, mixed mode debugging and just fitting in with the NDK/AS would also be quite productive.