Learning Rust
learning-rust.github.io
learning-rust.github.io
In order for me to learn anything, I need some form of "homework". If you want to teach me a new language, a new framework, I need to "get my hands dirty".
Working through exercises makes sure I actually understand what I am reading, and sometimes it even shows me I don't understand what I thought I did.
This is not specific to this github site. I've recently read the O'reilly Programming Rust Book, not a single exercise in it, and the official The Rust Programming Language Book also doesn't have any.
Could you expand on bit on what you see as the difference between an "exercise" and the "projects" that the book includes?
- Guessing game: https://doc.rust-lang.org/stable/book/second-edition/ch02-00...
- I/O: https://doc.rust-lang.org/stable/book/second-edition/ch12-00...
- Web server: https://doc.rust-lang.org/stable/book/second-edition/ch20-00...
There's also some exercises scattered at the end of various chapters, but not with the header "exercise"
- Control flow: https://doc.rust-lang.org/stable/book/second-edition/ch03-05...
- Collections: https://doc.rust-lang.org/stable/book/second-edition/ch08-03...
Sometimes they are even inlined with the text:
> Try modifying Cacher to hold a hash map rather than a single value.
> try introducing more generic parameters to increase the flexibility of the Cacher functionality.
- https://doc.rust-lang.org/stable/book/second-edition/ch13-01...
The second list of examples you gave does seem like the right sort of thing. I'm guessing the earlier commenter overlooked those because they're listed under the header "Summary," which kind of screams "skip me."
Hm, we certainly expect that this is possible. If this is too hard, we need some tuning!
For example, it's not like somebody's going to start TRPL, see "Let's make a guessing game," stop there and successfully make a guessing game — they don't know any Rust at that point! Similarly, IIRC we're not introduced to most of the IO functionality before the IO project, and so on.
Jake lists both kinds above; it's true that the project chapters are "follow along", but there are also suggestions for doing some extra stuff on your own.
Regardless, I think your overall point is correct: tons of projects is certainly not how we've structured the book. It is a thing some people want and would find useful. We'll see in the future.
The first few chapters actually mention and explain some of those gotchas (like ownership in regards to returning from functions or accepting a reference). The difficulty probably lies in not outright explaining everything, but not making the reader feel completely lost at the same time.
Then again, questions can always be added later on and if the basic reading material is good (which it is!), it's only going to make an already good source even better. I guess that's meant to say thanks for the Rust book.
The first day, for example, will kind of force you to figure out how to parse arguments, how to loop, how to convert strings into ASCII... all basic, practical tools that you will need sooner or later anyway. Now it's your job to pick up a Rust reference, look around for the tools that you need, and use them to solve an actual problem.
That's how I got very comfortable with D.
http://jordi.inversethought.com/blog/advent-of-d/
If you do this for Rust, I'd love to see a blog post like the above.
https://codeprep.jp/books?tags=&sortBy=createdAt&keyword=Rus...
The exercise style is "fill in the blank" so it's not as rigorous for learning, but still fun to get a sense of different language concepts.
On the surface, LYAH looks a lot more polished. It has nice drawings, less typos, seems like an actual book rather than a gathering of notes and thoughts turned into teaching material. But the exercises in LCTHW are amazing. They always challenge my knowledge in a way that often makes me realize that I didn't understand anything from the prior paragraph.
In LYAH I usually tried following along in GHCI to get an intuitive idea of the functions and patterns used. Yet, whenever I sit down to just build something that, while using the same features, deviates from the example code quite a lot, I often notice glaring holes in my understanding of the topics.
And so, bottom line, I want teaching material to ask hard questions which challenge my assumptions and perceived understanding. As a beginner, I can't come up with such questions on my own. Just presenting me with already assembled programs and going through them line by line just doesn't work (for me at least).
> I am a Sri Lankan Web Developer who lives in Vietnam. So I am not a native English speaker and just learning Rust
This guide is so well done, props to you. I haven't worked with Rust yet but your docs make it seem so easy to work with.
What I miss from Rust learning material is a series of exercises that focus on reference, lifetime, ownership where you have to fix some code to make it compile.
> Small exercises to get you used to reading and writing Rust code. Includes practice reading and responding to compiler messages!
One note on borrowing/ownership that really made it click for me was that to move from &mut T to &T you have to transition through owning the value type, so:
&mut T -> T <- &T
Whichever scope holds the actual value-type is the only scope that can make that transition(absent cases like RefMut)
fn no_mut(a: &mut usize) {
*a = 10;
let b: &usize = a;
println!("a: {}, b: {}", a, b);
}
fn main() {
let mut foo = 42usize;
no_mut(&mut foo);
}
If such pointer weakening was not possible, how would you be able to call a method that takes &self on binding of type &mut self? Of course, you can't use a mutably while b is in scope. So, something like the following results in a compiler error: fn no_mut(a: &mut usize) {
let b: &usize = a;
*a = 10;
println!("a: {}, b: {}", a, b);
}I wonder if what I'm thinking of involved &mut self captures that were happening as part of an impl on a struct. There's definitely some cases there where I was getting tripped up on it.
use std::thread;
fn no_mut(a: &mut usize) {
*a = 10;
{
let b: &usize = a;
println!("a: {}, b: {}", a, b);
}
let b: &usize = a;
thread::spawn(|| {
println!("b: {}", b);
});
}
fn main() {
let mut foo = 42usize;
no_mut(&mut foo);
}
Similar code but the move throws an error(as it should).If you don't have the value type then you're constrained by the parent mut lifetime here so it's not just as simple as a conversion that you can then pass around. Otherwise you need to consider all the lifetime scopes which can get a bit unwieldy.
You cannot move any closure to spawn that captures a non-static reference, since there is no guarantee that the value will live during the lifetime of the thread. (The closure is required to be Send + 'static.) E.g., you can't do (moving to a non-Copy type :)):
let foo = String::new();
let t = thread::spawn(|| {
println!("foo: {}", &foo);
});
You could move the captures, including foo, but then foo cannot be used in its original scope anymore: let foo = String::new();
let t = thread::spawn(move || {
println!("foo: {}", &foo);
});
// This will give an error, because foo is moved.
println!("{}", foo);
Note that only moving values works, this does not compile (for the same reasons as the first example): let foo = String::new();
let bar = &foo;
let t = thread::spawn(move || {
println!("bar: {}", &bar);
});[0] Except in a case when there's &mut U reference, which points at some part of the object referenced by &mut T.
In my humble opinion python give the impression to move fast, but when you need to maintain the code base the rust compiler is simply too wonderful.
I'd say I spend similar time on the same problem with both, maybe a bit more upfront on Rust and a bit more on the tail with Python. This is, of course, disregarding libraries.
For example, this week I was working on a mechanism for one request to start a future and then all further requests for that resource to await that same future.
I implemented it in less than 5 minutes in Node by just storing Promises in a map. But I'm still not sure of the ideal solution in Rust. It's definitely outside of my familiarity zone.
But what I'm finding over the months is that my routine Rust code is pretty fast now once I've run the gauntlet of experiencing the same compiler errors over and over. And when I reach for Rust instead of Node or Python, it takes longer but my executable is 3mb and it's much faster without much additional expense.
Also, it's tough to do async work in an ecosystem that isn't async-everything, something easy to take for granted in Node and Go.
I guess the main draw for me to any given language is great libraries with great APIs. Python has those, Javascript has those, C++ has those, Rust... not so much yet.
Well... what makes (especially) Rust libraries great is the relative absence of bugs. I can use a Rust library and have great confidence some ugly bug won't bite me later on. The developers of the libraries you (don't) mention continuously struggle to achieve the same property.
So in a sense those libs are not at all great in the same sense that a Rust library is!
Perhaps that's because GIL isn't really helpful for preventing logical races? Yet it encourages a false sense of security?
That said, while I love the idea of Rust I find the language itself offputting somehow. I don't know, maybe I just need to give it another try.
I hate annoying little nitpicky stuff like it won't auto-upcast a u8 to an i32, for example. There should at least be a compiler flag to allow that.
I mostly love it though. The stuff that bothers me is relatively minor and I think will go away as I get more fluent with the language.
Ownership. References. Expressions. Error Handling. Enums & Patterns. Operator Overloading. Closures. Iterators. Collections. Strings & Text. Input & Output. Concurrency. Macros. Unsafe Code/FFI - the coolest part, they show you how to create a safe wrapper around libgit2.
https://www.amazon.com/Rust-Programming-Language-Steve-Klabn...
https://www.amazon.com/Programming-Rust-Fast-Systems-Develop...
I think both are good books, I already have the second one and preordered the first.
Do you expect people to start participating in that submission with zero comments now that it's three months from the top of the stack?
They asked me to run some commands and log output to measure packet loss/speed etc. and then told me that my connection had 2-5% packet loss which was causing all the problem and I need to talk to my ISP or get a better connection.
I switched my ISP after that and its not a problem anymore.
Anything you learned since May 2015 should still be very relevant. That's almost three years ago.