Saturday, December 5, 2015

Wrote my first Rust Program

Thought I would share my first Rust program, along with some thoughts about the experience.

This is actually a version of a Python script that I actually use about once a month. The goal of the program is to read and print out all of the lines from stdin, but only print out the first occurrence of each line so that you have only the unique lines.

For example, given a file that looks like this:

line with some stuff
line 0
line 1
line 1
line 0
line 2

The program should just print:

line with some stuff
line 0
line 1
line 2

Note, there is a standard Unix utility called "uniq" that does something partially similar, but only filters out duplicate lines when they are adjacent. uniq is typically use in conjuction with sort, which destroys the original order of the lines, so with this example, "line with some stuff" would end up at the bottom instead of at the top.

Here is the "finished" program:

use std::io;
use std::io::prelude::*;
use std::collections::HashSet;

fn main() {
    let mut seen = HashSet::new();
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        let line = line.unwrap();
        // For "fun", try removing the & to see what the compiler error message is
        if !seen.contains(&line) {
            // For "fun", try swapping these two statements to get a compile error
            println!("{}", line);
            seen.insert(line);
        }
    }
}

The resulting binary size for a "release" build (x86-64) is about 526K. Presumably this binary has no external dependencies so it would be easy to move to other Linux boxes with the same architecture.

Here are some thoughts on this experience:
  1. my most import "high level" observation I have is that type inference is bad for understanding what you "cargo culted" (this is different use of the word cargo from the cargo tool that comes with Rust!). I didn't realize that stdin was actually protected by a "mutex" which now explains what the lock() does. For the statement: "let line = line.unwrap();", I still don't understand! What was the type before and after the unwrap() call?
  2. installation of the rust compiler on Linux Mint 17.2 was trivial using the provided instructions from rust-lang.org
  3. the cargo build command seems to follow the route of other new languages like Go in being "Java" like in not requiring writing a Makefile (even though compiling a single rust file seems pretty trivial too)
  4. I got at least one error message while trying to write this which wasn't "GNU" enough for Emacs's compilation mode to parse correctly (some kind of macro error looked like a file:line:column but file was <asdf>.x.y or whatever)
  5. Rust is fairly new but has been in use for a while by the kind of people that use Stack Overflow so there are some "non current" answers out there which slowed me down a bit
  6. Compared to trying to use Vala, I would say this was a positive experience tooling wise
  7. Compared to trying to use Go, I would say this experience was pretty similar to writing the same program in Go
  8. Compared to C, I would still be writing my own HashSet! (more likely I would have written some Bloom filter like code with dynamic chaining to larger Bloom filters as the load increased just be manly )
  9. It would be interesting to write the same program in Swift now that Swift is open source

Why are you learning Rust?

This is a great question. An obvious short answer is that I a programming language enthusiast and learning new languages can help shape how I go about my day job and how I think about programming. Honestly though, usually I spend more time reading about alternative languages than actually sitting down to write code in them so Rust has me intrigued enough to go the extra step.

The real answer is that I would like to write my own "shell" (shells are programs like bash, zsh, etc.) and using a non-VM oriented language seems paramount so I can have a minimal binary. Of course, I definitely want strong support for unicode (especially utf-8) in any language I touch these days which Rust seems to have.

Suggested exercises to help you learn Rust

If you are writing your first Rust program that isn't "hello world", I put some comments into the sample so you can see two real error messages I got while trying to "cargo cult" my way towards this program (no pun intended).

Disclaimer

These are my opinions and not the opinions of more employer, etc.




No comments:

Post a Comment