So, as I'm working on the book with No Starch, we've been discussing the TOC. I originally added the "Learn Rust" section because I wanted to do a tutorial-based introduction. But it's been a bit tough coming up with good examples.
One reason that it's tough is that I don't want to play favorites with the ecosystem, and so we've had a "no external crates" policy. Which means there's not a lot you can really do, depending. I think that using crates provided by the team should be okay, though.
So, what would be some good, small projects that would be worth using as a tutorial? Any ideas?
Hey @skade, shouldn't your implem use a VecDeque and pop_front, pop_back instead of a Vec ? Because your messages are not treated in the order they are received there ?
Otherwise yes something low level with networking seems like a very good idea
My first non-guided Rust project was an n-queens solver, which I briefly described in a blog post. It helped me with iterators, and I expect it could be expanded to add parallelism.
belongs to the Rust domain: high performance stuff,
parallelism,
very visual results,
tunnable complexity (from a couple of hours hacking to infinity).
Cons:
likely too large (you can squeeze a raytracer on a post card, but it'll be messy),
uses floating point,
requires some amount of math.
Ray tracer is a best vehicle to learn and compare programming languages, which I am aware of (do write your own ray tracer in Rust, you'll like it!), but it may be an overkill for an introduction
I implemented a parallel version of the 4th Euler problem in rust after some struggle with borrow checker and with some help from community. Read further here if you want. I used combinations() from itertools.
I typically try to avoid algorithms in examples because they made reading harder so I'd be wary of something like ray tracing, especially with multiple dimensions if they just make it more complicated. As always though, you'd have to check. That example linked by skade looks fairly approachable.
I think a simple parser might not be too bad, for something simple like CSV which isn't too complicated. There are apparently variants with separators using semicolons and tabs also. It doesn't seem too bad.
Also, I have a C++ book and they teach you how to box text in *s. For example, given the input Potato, the output would be:
**********
* Potato *
**********
This can be generalized to vecs of strings:
**************
* This is an *
* Example *
* to *
* illustrate *
* framing *
**************
They also extend this to concating these text pictures together horizonally and perhaps vertically. Maybe like this but I'm sure you could use other schemes as well:
***********************
* This is an * Potato *
* example * *
* to * *
* illustrate * *
* framing * *
***********************
[EDIT]
The second example might be more primitive than you're interested in but they use it quite well as a base to discuss the language.
A simple TCP messaging server with a read and write thread that sends JSON data. Was a good starting point for me a year and a half ago when I started with Rust. It gives you a wide range of libstd (TcpStream, Threads, Channels), pulls in crates from crates.io (rustc-serialize), and you can get server and client in under 100 lines.
I'd be careful with wc. If the version in the book doesn't perform like the one in coreutils then people might poo poo Rust. ls is probably a good one to implement.
I think it would be unreasonable to expect an example code that needs to fit in about a page of space to perform like a production-quality version from coreutils.
If you look ie at "The C Programming Language" or even the new "The Go Programming Language ", they implement several Unix utilities within the first chapter [p. 23] of the book, but it is clear that their versions are not production-quality/full-featured ones, just imitations on the basic idea of said utility to demonstrate some features of the language.
As such, I don't think that having a wc example in the book is unreasonable, even if it performs worse than the coreutils version, since readers should understand that the example is there for the purpose of explaining the language, not for writing a production-quality replacement for coreutils' wc.
One scenario in which wc is blisteringly fast is counting lines, and practically the whole reason is the use of memchr(). I haven't tried very hard, but it's difficult to match using pure Rust code. If you tweak the Rust version to use memchr(), you'll get comparable performance. Other use cases don't require such tricks.
I would argue that anyone who rejects Rust because of an overly simplistic example in a tutorial book needs to check themselves
I think wc is a great idea as well. It'll introduce line and word oriented string processing and give a good indication of how a relatively simple problem is solved in the language.
Complex examples don't work well in a tutorial setting IMO because the reader is still cementing the details around the language in their brain and if you throw a giant mess of code at them, they're trying to understand both the complex algorithms at play AND come to grips with unfamiliar syntax / conventions, results in a mess.
That's cool. I know there are a few coreutils projects kicking about on github and some of them have performance issues. The reddit thread I linked to is about a year old so it might be out of date.