Two Beautiful Rust Programs
This is a short ad of a Rust programming language targeting experienced C++ developers. Being an ad, it will only whet your appetite, consult other resources for fine print.
First Program
This program creates a vector of 32-bit integers (std::vector<int32_t>
), takes a reference to the first element, x
, pushes one more number onto the vector and then uses x
.
The program is wrong: extending the vector may invalidate references to element, and *x
might dereference a dangling pointer.
The beauty of this program is that it doesn’t compile:
Rust compiler tracks the aliasing status of every piece of data and forbids mutations of potentially aliased data.
In this example, x
and xs
alias the first integer in the vector’s storage in the heap.
Rust doesn’t allow doing stupid things.
Second Program
This program creates an integer counter protected by a mutex, spawns 10 threads, increments the counter 10 times from each thread, and prints the total.
The counter
variable lives on the stack, and a pointer to these stack data is shared with other threads.
The threads have to lock the mutex to do the increments.
When printing the total, the counter is read bypassing the mutex, without any synchronization.
The beauty of this program is that it relies on several bits of subtle reasoning for correctness, each of which is checked by compiler:
-
Child threads don’t escape the
main
function and so can readcounter
from its stack. -
Child threads only access
counter
through the mutex. -
Child threads will have terminated by the time we read
total
out ofcounter
without mutex.
If any of these constraints are broken, the compiler rejects the code.
There’s no need for std::shared_ptr
just to defensively make sure that the memory isn’t freed under your feet.
Rust allows doing dangerous, clever, and fast things without fear of introducing undefined behavior.
If you like what you see, here are two books I recommend for diving deeper into Rust: