Learning Rust 0.9 the Hard Way (read: on my own)

Rust 0.9 the Hard Way

Recently I read about a relatively new language called Rust. My understanding is that it’s similar to C, but has a focus on memory management, concurrency, and safety. I’m not sure what the “safety” part means, but I suppose I’ll find out eventually. Since it’s version 0.9, features are bound to change quickly until 1.0 comes out at the end of the year. Still, my background is primarily in web-based languages, so I thought I’d tackle a systems (compiled) language just to diversify my skill set.

The interesting thing about this project is that I’ve actually found myself writing new PHP and Ruby code that I never would have written before. In order to learn Rust, I’ve decided to reinvent the wheel by implementing common algorithms, such as the Fibonacci Sequence, the Levenshtein Distance algorithm, and so on. There’s a good list over at Rosetta Code

The first one we’ll tackle is the Fibonacci Sequence. This is one of the easiest sequences out there. You can read the whole story on Wikipedia.

But first, let’s learn some basic Rust. Once you’ve installed Rust, it’s time to create our first program.

Hello World

hello_world.rs


fn main() {
    println!("Hello, world!");
}

This is pretty straightforward. Rust starts off by calling a function called main(). This main() function is where everything gets started.

Next, we’re going to call println! and pass in parameter of “Hello, world!”. The println command prints a line. The ! at the end indicates that it’s a macro. I haven’t quite figured out the difference between a macro and a function, but for now, let’s just roll with it.

If you compile this by running rustc hello_world.rs and then execute ./hello_world, you’ll find that the Rust program has printed out “Hello, world!” on your screen. Nicely done!

Variables

Immutability vs Mutability

Like any programming language, Rust has a concept of variables. Low-level languages tend to make you do really convoluted stuff to ensure that you’re using memory wisely. Since Rust has a focus on memory management, some of this is taken care of for you. However, we do want to be smart about it, so when we declare a variable, we want to decide whether it’s mutable or immutable. Immutable really just means that you can’t change it — you have to create a new version of it, if you want to change the value. Here’s what declaring an immutable variable looks like:

let foo = 1;

The keyword let says that we’re declaring a variable called foo and then we assign the number 1 to it. Since this is an immutable variable, if you were to try to change it, you’d get an error!


let foo = 1;
foo = 2;

Oops! But we want to change it, Rust! How do we do it? Well, we say that it’s mutable by declaring the variable with the mut keyword:


let mut foo = 1;
foo = 2;

There. Now that worked!

Sizes

Another thing we have to worry about if we want to be smart about memory and speed is the size of our variables. In Rust, there are two ways to do it. Let’s look at both of them and see what happens:


let mut foo = [1,2,3]; // a vector (or array) of ints containing 1, 2, and 3
let mut bar = ~[4,5,6];

The first example is a regular, fixed-length, mutable vector. If we try to add another item to it, we’ll get an error!


let mut foo = [1,2,3];
foo.push(4); // error: type `[<generic integer #2>, ..3]` does not implement any method in scope named `append`

This means that if we’ve defined foo = [1,2,3] what we’ve done is create a vector of generic integers with a length of 3 (as indicated by , ..3).

The second line is a dynamic, mutable vector. The ~ sign lets us decide that it’s not fixed-length, and we can add more stuff to it later!


let mut bar = ~[4,5,6];
bar.push(7); // success!

As a general rule, you want to keep things as fixed as possible to save on memory and increase efficiency, but sometimes you just need a dynamically sized item.

Fibonacci Sequence

Ok, now that we know how to define variables and put them in a function, let’s build the Fibonacci Sequence generator.

Rules for generating numbers

  • F0 = 0
  • F1 = 1
  • Fn = F(n-2) + F(n-1)

The results look something like:

  • F0 -> 0
  • F1 -> 1
  • F2 -> 1
  • F3 -> 2
  • F4 -> 3
  • F5 -> 5
  • F6 -> 8
  • … and so on

Now that we know how a Fibonacci Number is calculated, let’s generate some!


fn main() {
    let max = 25;
    let results = fibonacci(max, ~[]); // pass in max as arg1 and an empty, dynamically-sized vector as arg2
    println!("{:?}", results); // Print the results as a string. "{:?}" lets us print anything.
}

// @param uint - max - an unsigned integer, the number of Fibonacci numbers to generate
// @param vector - list - a mutable, empty, dynamically sized vector of integers
// @return ~[int] - we're going to return a list of integers
fn fibonacci(max: uint, mut list: ~[int]) -> ~[int] {
    if list.len() == 0 {
        list = ~[0,1]; // If the list is empty, give it 0 and 1 as first to items (see rules above)
    } else if list.len() == max {
        return list;
    }
    // Get the last two items on the list 
    let n1 = list.len() - 1; // Last item 
    let n2 = list.len() - 2; // Second-to-last item 
    let f1 = *list.iter().nth(n1).unwrap(); // Get the (n-1)th item 
    let f2 = *list.iter().nth(n2).unwrap(); // get the (n-2)th item 

    // Add them together and push the sum onto the list! list.push(f1 + f2); 
    // Get the next number with the new list 
    return fibonacci(max, list)
}

 

Whew! That’s a lot of code. It should all be pretty straightforward, except for lines 18 and 19. Let’s break down line 18 and see what’s happening:

18: let f1 = *list.iter().nth(n1).unwrap()

We’ll skip the * for now. The iter() method converts the list of integers (~[int]) into something iterable. If we wanted to, we could do a for loop on list.iter(). But in this case, we don’t need to iterate on it — we just want the nth value. And that’s what nth(n1) does. It gets the value at the index of n1 on the list.

The last bit is unwrap(). The result of nth() looks like this: Something(3). This is a result of how Rust returns things to let us know whether it found anything or not. According to the documentation, if there is nothing at that index, nth() would return Nothing().

Since Something(3) is not a number, we want to “unwrap” that to get to the number inside. What we wind up with, after everything has been processed (excluding the *, which we’ll come back to) is:

let f1 = &3

The & says that it’s a reference, so we want to dereference it so that we just wind up with the integer. The * is the keyword/symbol for dereferencing something. Think of the * as canceling out the &. Now we’re left with:

let f1 = 3

If you compile this script by typing rustc fibonacci.rs, it should succeed. Run the script ./fibonacci and see the first 25 numbers in the sequence! You can confirm these numbers with a simple Google search or by writing out the numbers yourself.

Conclusion

I know that was long-winded, and I know I probably completely mangled some of the definitions and reasons why I did things the way I did, but like I said, I’m teaching myself as I go. This is representative of my current state of understanding things, and now, after reading this entry, you should also be caught up with me.

Hope this helps someone!

Does your financial institution encrypt your passwords? Mine doesn’t.

Last year I set up a 401K contribution with my company. In May, my company was acquired and rolled into a larger company. The larger company set us up with a new 401K provider, Kibble & Prentice. I filled out the required paperwork and it was done. That was last summer around July or August.

Fast forward to a week ago in mid-March 2013. I decide to check out the 401K status, so I try to log in. The login info provided to me earlier didn’t work, so I hit “Forgot User ID”. I answered the provided question and it said that there was an error. I tried a few other variations just to make sure and then decided that I just hadn’t set the security questions. The instructions on the site said to call customer service.

I grabbed a conference room at the office, dialed the number, and talked to a representative. She was incredibly nice and helpful. I said “I lost my user ID and password.” She says, “I’m sorry. Can I get your social security number?” I provide it. “Can I get your zip code?” I provide it. “And finally, your date of birth?” I provide it.

Then she says — and pay attention closely to this:

“Your user name is (blah blah blah) and your password is (blah blah blah).”

Read that again and let it sink in. I’ll wait.

For those who haven’t figured it out, she told me my password. This should not be possible. She should not be able to read my password at all.

In programming one of the cardinal rules of security is that passwords should never, ever be readable. They should be encrypted using one-way hashing techniques such as md5, sha1, bcrypt or any number of other hashing techniques. The security of those aren’t perfect, but they’re a huge, huge step forward from storing them in plain text.

Here’s what an md5 password might look like:

210d53992dff432ec1b1a9698af9da16

As you can see, that’s not easy to guess — and a customer support agent certainly could not translate that into my original password!

The logical conclusion here is that Kibble & Prentice, the company that has been selected and trusted with my financial information and retirement money, stores my password in plain text. That means anyone with access to the database, including, apparently, customer service representatives, can read my password and access my account.

This is disconcerting to say the least. Any disgruntled employee could simply dump the database into a text file using a query as simple as (assuming a SQL-like language):

SELECT username, password FROM users

And bam! Instant access to every user’s account. Including mine. Including yours. Including anyone who uses Kibble & Prentice as a 401K provider.

Do I trust them with my money? Not anymore.

Now all I have to do is figure out how to get my money out without losing half of it to taxes.

Bottom line: If I were you, I’d call up your financial institutions and pretend you lost your username and password. A secure institution will send you a “Reset Password” link. An insecure one will read your password right back to you over the phone.

I can’t even describe how disgusted I am with Kibble & Prentice right now. Beyond words.

If your company uses Kibble & Prentice for your 401K provider, I’d complain. I’d complain loudly and vociferously until everyone knows. I’d complain right now and I’d get them to switch to another provider who treats your data and money with the respect and care that you deserve.

Chasing Waterfalls

Last night was the first night of track practice in Run365′s 16-week training program. I arrived early — way early — at about 6:00. It didn’t start til 6:30. I spent the next fifteen minutes wondering if I was in the right place, but fortunately, some people showed up and I realized I was not alone.

When the coach, Andy, finally showed up, we went over some base rules about how to use the track, proper etiquette, and what the overall plan was. We then ran two laps around the track (about a half mile) and then did some dynamic stretching in the field. It was all pretty standard stuff that I had expected. Then Coach Andy tells us what kind of exercise we’re going to be doing on the track. Something called “waterfalls”, though the less-PC term is apparently “Indian Running”. The gist of it is that you run in a group in single-file at a consistent speed. The person at the back of the line then sprints up to the front. When she is in position, the next person sprints forward, and so on. Eventually, the first runner will be at the back of the line again, and the process starts again.

We ran 3×10, which meant that we ran waterfalls for 10 minutes three times, with a 2-minute break in between. It was hard. Harder than I thought. They split us up into pace groups, and I (wisely, as it turns out) opted to go with a slower pace group (10:45) rather than the pace I generally run (10:00). I figured that I should be conservative for my first track practice, and if all goes well, then next time I’ll go a little faster. I did well enough that next time I can definitely go faster, but we’ll see what the next exercises are.

Our pace leader, Leela, decided to have one person call out a topic as they sprinted to the front, and then the rest of the group would call out something that has to do with that topic as they sprinted up. The idea was to take our minds off running in circles. I tonly sorta worked for me. Due to my hearing loss, I didn’t hear very many of the categories — or, indeed, very many of the responses. Instead, I just mentally thought about problems in my life and how to deal with them. Nothing major. Simple things like: when will I have time to do my laundry? Am I over-committing myself? When will I be able to go scuba diving again? And so on. The time flew by quicker than I thought.

When we finally finished, my legs were clearly tired and I knew they’d be sore in the morning. We ran down to the middle of the field for cool down stretches and a core workout.

I learned I suck at planks. Note to self: plank.

I also learned that Coach Andy was right. He told us at the kick-off meeting that track running is more mental training than anything else. During the last 10-minute waterfall run, I kept wanting to ask Leela how much farther we had to go. I wanted to stop. I wanted to sit down. I wanted water. But I forced myself to shut up and keep running and not slow down. I told myself I’d be happier if I finished without stopping, that my girlfriend would be proud of me, and that I’ve been through things so much worse than this. If I could handle those, I could handle a few more minutes of running. So I did. I kept running. And I finished it without complaints.

I can’t say so much about the planks and other core workouts, but I haven’t done those exercises in years. I’m sure soon enough I’ll be planking with the best of them.

If the rest of the practices are anything like tonight, I’ll be faster, stronger, and thinner in no time flat. San Francisco Half-Marathon, here I come.

Tuesday HM Training – 2/26/13

I skipped my Monday Night run in favor of Nerd Nite (East Bay). Totally worth it. Instead, I resolved to run 4 miles last night to make up for missing my Monday night run. I got home from work, and I was exhausted. It was cold outside, and I was hungry. I did not want to run. I texted my girlfriend, and I said, “I don’t want to run. Make me run.”

Of course I knew that I couldn’t slack off, not if I expected to complete this training. I pulled on my running gear and I stepped outside. It wasn’t quite as cold as I thought, but I still found myself bouncing up and down as I walked down Townsend toward Embarcadero. The five-minute walk is my warmup period, and I do a couple of skips and hops and stuff to get warmed up. By the time I reach Embarcadero, it’s run time.

I have a new gizmo. It’s a hearing aid with bluetooth capabilities. I started up Nike+ Running app on my iPhone, and then started up the Strava Running app. I use Nike+ because it’s more social, but Strava is where I really track my training.

My goal was 10:00 per mile, or as close as I could get, and I was going to run 4 miles. My foot hit the sidewalk on Embarcadero, and I was off!

The first mile was easy, as usual. I must have passed 30 other runners in the first mile. I presumed they were training for the SF (Half) Marathon as well, a suspicion that was confirmed when the last few people in the group ran by wearing SF Marathon jerseys. I made a mental note to get one of those too.

When I reached the Ferry Building, my iPhone started cheering. Someone had “liked” my run status on FB. It’s unreal how much of a boost that actually is, and I picked up speed. My first mile was a bit fast at 9:34. I slowed down a teensy bit and continued on.

The second mile ended just after Pier 23 at a pace of 10:00 per mile. By the time I reached that, I was in full on run mode. My body was completely warmed up and I was hitting my stride. Every once in a while I would get discouraged as people passed me at blazing speeds, but I consoled myself with the hope that by the time the SF Half Marathon comes around, I’ll be running faster. Hopefully.

Halfway through the third mile I some more cheering, though I could feel myself tiring. I managed to finish that mile at a 10:27 pace. I knew I had to speed up if I was to meet my goal of 10:00 per mile.

There’s construction along Embarcadero, so the sidewalk is all messed up. In addition, there is very little light, which makes it dangerous for runners. As I ran through that particular section, I happened to see something moving: a skateboard. Some asshat had pushed his skateboard forward as he walked up to it. If I hadn’t been looking at the ground because of the torn up sidewalk, I might have run right onto it without noticing it. A black skateboard on black pavement in the dark? Recipe for disaster right there.

I was furious, but I channeled my anger into speeding up to meet my goal, and I finished the 4 mile mark at 10:01 per mile. Final time: 40:02. Goal met.

I looked at my phone, and my girlfriend’s belated text read: “You will be that much sexier if you run!”

Consider me sexy.

Half-Marathon Kick-off Post

Last January, I was inspired by a friend to take up running. My family and friends — and quite frankly even I — thought I had lost my mind. Running had always been near the top of the list of things that Brian Doesn’t Like (right behind lettuce — gross!). Given my level of physical activity over the previous few years and the prospect of participating in events with my friend, however, I decided to give it a shot.

I downloaded a Couch to 5K app (C25K Free) from the iOS App Store and began my run. The Couch to 5K plan is simple. It starts you off running for 60 seconds and walking for 60 seconds and as the weeks go by, slowly ramps you up to running for 30 minutes straight. They assume you’re running a 10 minute mile, which is unrealistic at best for a beginner like me, but it was the longest I’d ever run without stopping — by far.

By April, I had run my first 5K race. By July, I’d run three 5K races. In November, I entered my first 10K race — and I did it! My time was about 1:16, which isn’t too bad for someone who had only been running for under a year.

Just after finishing my first 5K race with Elly! It was harder than I thought!

At about the same time as the 10K race, I began dating my girlfriend. She’s a triathlete (insert gulp here) and really inspired me to go further. In January, I decided that this year’s goal was to run a half marathon. Am I crazy? Yes. Yes, I am.

My girlfriend trains regularly in three different areas: swimming, cycling and running. Her swim sessions involve a masters team at a local gym. A coach monitors the training and provides a training regimen for them to follow. She runs with another coach and team on the track once a week or so as well. Her cycling is less structured but involves biking 30+ miles on Saturdays and sometimes on Sundays. She also commutes to work.

Taking a cue from her (and a fair bit inspired by her tenacity), I decided I would find a group that was around my skill level in running and use that as a base for training for my half marathon.

I can’t remember exactly how I found Run365.org, but I thought the idea was great. They have a 16-week training program for the half marathon, and it started a week after I found out about it! Perfect timing!

I paid up the $150 for training, plus another $100 to sign up for the SF Half Marathon. This is it. It’s real. I’ve committed to running a half-marathon on June 16, 2013. Gulp.

The kickoff session was this past Saturday. We met at the Sports Basement in the Presidio, where the coaches introduced themselves and split us up into pace groups. Normally I run a 9:30 mile, but that’s my race pace, so I figured I’d drop back to the 10:00-10:30 mile pace group and run with them. It was a good decision.

The pace group leaders introduced themselves quickly and then we began running a short 3 mile run. (Did I really just describe a 3 mile run as “short”? Holy cow…)

It was not a good run. I was out of breath the whole time. I’m still not sure what happened or why I was having such a hard time, but thanks to the moral support of my girlfriend (she ran with me, even though she runs 8:30 miles), I managed to finish the run without stopping — exactly at 10:00 minutes per mile.

The run was interesting for a few reasons. Normally I run with music, but I had left my headphones at home, so I didn’t have that with me. Additionally, I normally run solo, but this time I was surrounded by 20 other people in my pace group. I’ve never been one to talk while running, but my girlfriend struck up a conversation with one of the pace group leaders — Hillary, a really enthusiastic, exuberant redhead — and that helped keep my mind off my running.

The run schedule for Run365 is simple: Mondays are fun run nights, Wednesdays are track nights, and Saturdays are LSD (Long Slow Distance) – runs. On Tuesday, Thursday and Friday, I’m on my own. Sunday is a rest day. I had to miss last night due to Nerd Nite (which will pretty much always take priority over anything else, sine it’s my favorite thing to do), and this Saturday I’m going to have to miss the LSD run because I’ve signed up for The Color Run at the same time.

Celebrating post-Color Run 2012!

I’m looking forward to the Wednesday night track night. I’ve never really done intervals on my own, so it should be interesting. Starting next, week, I’ll go to all the practices (or as many as I possibly can). My plan is to document them here, so that I can look back and see my improvement over time, and hopefully remember details about the runs that I would otherwise forget.

Keep runnin’!

Have a good life

This past weekend my grandmother passed away at the young age of 92. She lived a long, full life, and while I miss her dearly, I’m thankful for having the time and opportunity to tell her everything I wanted to before she passed. My father asked me to speak at the funeral, so I wrote a little bit about my thoughts regarding my grandmother — my Nana. Many people asked me to send it to them, so I decided I’d also post it here as well.

I have many fond memories of time spent with Nana, and for those who knew her well, it will come as no surprise when I say that many of those memories revolve around food. Every once in awhile as a kid, I’d go over on a weekend and she and I would make cookies from scratch.
When I was growing up, my family and I would go to Nana’s house every week or two for dinner. She’d cook these huge meals, and we’d sit around the table and have a good time. Nana would always make sure that we were spoiled grandchildren, slipping us some cash or candy when our parents weren’t looking.
During Hanukah, she would make potato latkes and the best cheese blintzes I’ve ever had. To this day, it’s my favorite meal. Over the last few years, she couldn’t cook as much as she used to, but somehow, miraculously, when Hanukah rolled around, she’d have a few cheese blintzes for me to eat.
On my birthdays, she would always bake a cake. A coconut cake. Blech. I never liked did like coconut. I suppose it was her favorite, because I think she made one for everyone’s birthday. But year after year, my birthday would roll around, and we’d be around that big wooden table again. The lights would go out, and my grandmother would walk in with the candles lit, and I would see this big, white coconut cake.
I’d blow out the candles — or try, anyway. She had a tendency to buy those “magic candles” that never actually go out.
One particularly memorable year, she came out with this cake, and I’m pretty sure I groaned aloud. I blew out the cake, and waited for ice cream to be served. I would just eat ice cream instead, and let the grown-ups eat the coconut stuff. But then, out of nowhere, appeared another cake — a vanilla cake. She had remembered.
Even when she finally moved out of the house in Mountain Brook and into an apartment, she never stopped spoiling me. When I came to visit from college, she’d give me giant chocolate bars and diet Coke. It’s a wonder I have any teeth left at all.
As I grew older, I began to appreciate how much she cared about my well-being, and the well-being of my brother and my parents and everyone she knew. She’d always ask how everyone was doing, and she didn’t hesitate to offer her opinions on my life, whether it had to do with my health, my job, or my education.
The last time I saw her was in August. I came home to celebrate my great-aunt Janis’s 90th birthday. I took the opportunity to visit Nana as well, though by the time I arrived, she had gotten sick and wound up in the hospital. I saw her that day, and I came back the next to make sure everything was okay. I knew she hadn’t been doing well for a long time, and more than anything, I wanted her to know that I loved her very, very much.
We sat in the hospital room with my dad. The Olympics were on with some sort of amazing gymnastics dance thing. We all talked for a bit about things. She was embarrassed that I had to see her in a hospital, but I didn’t care. She’s my Nana. I was just glad to see her.
As visiting hours ended, I leaned over and gave her a hug and a kiss, and I said, “I love you, Nana.” I didn’t know how much longer she had in this world, but I wasn’t about to let an opportunity go by without telling her so.
She smiled at me and said, “Have a good life.”
“Have a good life.”
I’ve been talking this whole time about what Nana means to me, and my focus every time I thought about her since then was to let her know how much I loved her. It was about how much *I* loved *her*.
And her last words to me weren’t about how much *she* loved *me* — they were just about *me*.
That’s the kind of woman my grandmother was. That’s how I’ll always remember her, and it’s the kind of person I will strive to be.
You always think this is easier when you see it coming, but it turns out it’s never easy at all. You always think there’s more time, until there isn’t.
I love you, Nana. Always will.
I’ll be honest, guys. As far as grandmother’s go, Nana is pretty great.

Chaucer invents Ass Kissing

Today at work someone made a fart joke, which triggered a long-forgotten memory of my graduate studies. No, I didn’t study the Physics of Flatulence. I studied the English language, or more specifically, English Language Arts Education. The class in question focused on Geoffrey Chaucer, including the legendary and unfinished work of The Canterbury Tales. While considered one of the greatest of classics, it is also one of the most versatile of all the classics I’ve read.

That is, it has a story that would appeal to everyone.

Unfortunately, Chaucer croaked before he finished the book. What kind of author does that to his fans, anyway?! Ahem. But I digress.

Dear George R.R. Martin, Fart jokes are more fun than pedophilia. Love, Geoffrey

For my coworker, I’d imagine the story of The Miller’s Tale would be particularly humorous. You should really read the original, but in case your Middle English is a bit rusty (I don’t blame you — I blame the Great Vowel Shift, but that’s another story…), I’ll summarize for you:

There was this guy named John who was married to a beautiful woman named Alison. John decided to rent out an extra room in his house for some money to a student named Nicholas. Nicholas takes a fancy to Alison and starts an affair with her.

In order to get John out of the way, Nick tells him that the Second Flood is coming and that he should sleep in a boat tied to the ceiling of his house so that when the flood comes, he’ll be prepared.

Let’s just say John is a moron.

So Nick and Alison are bumpin’ uglies when Absolon, another man in the city who also has a thing for Alison, shows up outside the window and starts singing love songs to her. She says he can kiss her, but instead of leaning out the window, she sticks her ass out the window and Absolon literally kisses her ass.

Let’s just say Absolon is a moron as well.

Absolon gets pissed, brings a hot iron brand back, calls for another kiss, and this time Nick thinks it might be funny to stick his own ass out. Absolon brands Nick, who then screams, waking John up, who thinks it’s the Second Flood and cuts the rope, falling to the ground and breaking his arm.

To reiterate, John is definitely a moron.

It’s really, really funny, but that’s the gist of it.

Smooch this, Absolon!

What’s really interesting about Chaucer’s work is that while The Miller’s Tale is quite crude and raunchy, many of the other tales are not crude or raunchy at all, but rather about more serious topics. The topics that Chaucer tackled in his Tales were often controversial for the time, such as The Wife of Bath’s Tale (women’s rights), The Prioress’s Tale (anti-Semitism), The Friar’s Tale (religious hypocrisy), and The Knight’s Tale (chivalry).

These topics are often covered by controversial movies today! It’s a little absurd that we still have to worry about these things nearly 600 years after Chaucer’s death in 1400.

Every once in a while, someone asks the question “if you could meet any historical figure, who would it be and why?” For me, the answer is always simple: Chaucer.

I really hate not knowing how things end.

Theodora, Empress of the Byzantines

I almost titled this post “Theodora, wife of Justinian I,” but that would be misleading. All accounts suggest that Justinian treated Theodora as an equal, and in fact, she is much more responsible for his success than he is. But I’m getting ahead of myself here.

Last night I decided to watch a documentary on the Dark Ages. It was really fascinating for a lot of reasons. The most obvious one is that I thought of the “Dark Ages” as this kind of boring, barbaric time period where nobody really knew much of anything and nothing really happened because everyone was dying of the Bubonic Plague. It turns out I was only partly right: half of Europe died but lots of other fascinating stuff happened, too.

After the Visigoths invaded and the Roman Empire fell apart, there was a century or two where chaos reigned and most of Western Europe (pretty much anything west of Rome) turned into squabbling warlords. All the great technology went away, and people just hung on for dear life. If you were a peasant in those times, life was hard. Really hard.

In the mid 6th century A.D., a man named Justinian came up with this ambitious plan to revive the Roman Empire and turn the Mediterranean back into a “Roman lake”. At first when I heard this, I didn’t really understand what it meant. The Mediterranean isn’t a lake! It’s a sea! If you think about a lake, however, you realize that it’s surrounded by land. In this case, Justinian wanted to surround it with Roman lands.

He got himself crowned emperor of the Roman Empire, though we call it the Byzantine Empire now, since it was formed in what is now Turkey and it never really lived up to the ideals and grandeur of the Roman Empire. He spent tons of money trying to take back all the lands that had once been controlled by the Roman Empire, and he achieved a lot of his goals. Specifically, he conquered northern Africa, Italy, coastal Spain, and Jerusalem, effectively making the Mediterranean a “Roman lake” once more. However, he had major problems with money. More accurately, he had none.

He would cheat his soldiers, forge documents to get their possessions willed over to him when they died in combat, and flat out lie and scam his way into more money. What a psychopath, right?

Kinda like this guy. Only less nice, and his sister was probably not as hot as Deb.

Worse, when the soldiers and the people had enough, they revolted, and rather than realizing the error of his ways, he tried to flee. But his wife, the beautiful Theodora, called him out on it, and is almost single-handedly responsible for Justinian’s redemption and continued success.

It took me a while to figure out that those white dots were jewels in her crown. Very cool!

Theodora was raised as a peasant and became a dancer and courtesan (in blunt terms: a stripper and prostitute, though there was more dignity afforded to courtesans at that time). It was in a burlesque show that she met Justinian. Shortly thereafter, they were married.

Empress Theodora was fascinating for a lot of reasons. She was beautiful, strong-willed, and clearly an equal to (if not greater than) Justinian in nearly every way. When the Nika (literally: conquer!) riots began, Justinian and his council decided to flee rather than be killed by the mob. It’s hard to blame them. The Nika riots turned out to be one of the most deadly riots in history, with over half of Constantinople burned to the ground and tens of thousands of people killed. It’s no wonder Justinian decided to flee.

I live in a neighborhood where there were very minor riots following the San Francisco Giants’ victory in the 2012 World Series, and I was scared shitless and stayed in my apartment and hoped my building didn’t catch on fire. I couldn’t imagine living in a city where tens of thousands of people were killed for no good reason! Crazy.

But I digress. As Justinian and the others prepared to leave, Theodora stood up and called them out for being a bunch of pussies. She said that “purple makes a fine shroud.” Since purple is traditionally associated with royalty, she was implying that it was better to die as an emperor that to live as an exile. Justinian insisted upon leaving, but Theodora said he would be leaving without her, and she turned back to the city.

Theodora was the Biff to Justinian's McFly.

If modern men are any indication, Justinian probably felt like a giant pussy and decided that if his wife could face this screaming mob, then perhaps he could too. He returned to the city and ordered his soldiers to kill everyone. Well, not everyone. But you know.

Eventually, Theodora’s strategy proved to be the right one, and the two of them reigned for many years.

It’s easy to focus on Justinian, since he was the man and history tends to focus more on the men than the women, but I don’t want to understate the importance of Theodora’s actions. Without her courage and determination, Justinian would have fled and the Byzantine Empire would have collapsed immediately, losing all of its progress and relevance. Instead, we can thank Theodora’s metaphorical cojones for allowing Justinian to stick around and turn the Byzantine Empire into something formidable. Thanks to her, we got the Hagia Sophia, the greatest cathedral in the world and widely considered on of the Seven Wonders of the Ancient World.

To this day Theodora stands as a model for all women. She rose from the lower class to the highest rank in the empire. She was secure in her sexuality and her body image. She had more courage than her husband and his council. And most of all, she stood up for her convictions.

If this story from history proves anything, it’s that men aren’t always the best rulers and the best people to put in charge. Women can do just as well, if not more.

If you’re interested in learning more about Theodora, you can check out her Wikipedia entry or read this awesome book:

Interesting View – Google Maps 45 Degrees

Today I read on TechCrunch about Google’s new 45-degree maps. As I was clicking around exploring, I found this little tidbit:

 

 

This is the top-down view from Google Maps of what appears to be an oval-shaped area in a town square. There is an obelisk in the middle, which leads me to believe this is some sort of sundial-esque thing. But that’s not the interesting part. The interesting part is that when you zoom in one more level, Google converts it to 45 degrees, and it looks like this:

See the difference? In 45-degree mode, it’s a perfect circle. Interesting, right? You’d expect it to be the other way ’round — circular from above, elliptical from an angle. But it’s not.

Zoom in even further and you find out that it’s not a drawing or paint. The design consists of actual tiles that have been there for who knows how long:

Cool, right? Right.

Here’s a link to the map itself, so you can play around with it:

Getting Shit Done

“Why did you hire me?” I asked my boss over dinner one night. I explained that I had witnessed the hiring process for dozens of applicants for various positions, and it’s very clear to me that we have a very high bar for excellence that must be met or exceeded before extending an offer to a job. When I applied at my company, my experience in web apps was non-existent. I was moving from podunk Alabama over to Silicon Valley. For some reason, he took a chance on me and hired me.

What could I have possibly done in my interviews to get this job? I had been wracking my brain for a year trying to figure this out. He laughs for a second, and then he explains.

He laughed and gave lots of reasons, but the one that stuck out in my mind was this one:

You had this “I’m gonna get shit done” attitude that most people I talked to didn’t.

I’ve been thinking about this for a while — it’s been two weeks since that dinner — and  I’ve reached a few conclusions about what he meant. There are two main definitions of “getting shit done”, in my opinion:

  1. Taking initiative to solve problems (e.g., learning a new language, building a new feature)
  2. Helping other people solve their problems

The first point is self-explanatory. I think we all do this to some extent — especially the “rockstar” developers out there. It’s easy for a single developer to build a feature, learn a new language, or take on a little extra responsibility. In fact, I think ti’s a point of pride for most developers (including myself) when they Get Shit Done in this manner.

But as cool as it is to come up with a new feature, spec it, and implement it by myself, I think the second part is far, far more important: supporting your team.

One of my primary duties at my job has always been handling of support tickets that came in from Ops. Initially it was a way for me to learn how our custom codebase worked and figure out all the different parts of the app, but over time it was clear that I’m pretty good at multi-tasking and jumping from one thing to another. For instance, I may be knee-deep in a new feature, but when a support ticket email Growl notification pops up, I jump over to email, read the ticket, fix the problem, push to Github, issue a pull request, and jump back knee-deep into my feature code. I don’t exactly know how my brain handles it, but somehow it knows where I left off.

It has recently been brought to my attention that most developers can’t do that. It’s focus on one thing at a time, then focus on another, then focus on another, with no quick jumping back and forth between things. Blew my mind.

But the flip-side to this support ticket thing is that I know almost everything about how our app works. I know where all the features are, I know what all the settings are and exactly where to find them, I know which methods get called by which actions, and so on and so forth.

All day long people bombard me with questions:

  • “Hey Brian, is this a bug? (link to support ticket)”
  • “Dude, do we have an easy way to generate random strings for test data?”
  • “Where is the fee ledger?”
  • “When we syndicate listings, does such-and-such data go out in that feed?

They ask me because I know the answers — and if I don’t, I can find out quickly. They also ask me because they know I’m more than happy to help. I’ll drop whatever I’m doing to make sure this other person can get their job done. And finally, that even when I drop what I’m doing, I can easily get started again when I’m done helping.

Slight digression here. My Bachelor’s degree is in Theatre. I have been in countless productions on stage around the country, and it’s something I’m truly passionate about. One of the things that I learned early on (that most actors don’t seem to get) is that, to quote Jack Shepard, “we live together or we die alone.” The ensemble on stage is only as good as its weakest link. If one actor dropped their line on stage, it was up to someone else on stage to cover for the mistake. I can’t tell you how many times someone has had to step in and improvise a line to get the script back on track when one actor forgot what their next line was. Sure, it sucks for the actor that dropped the line, but it’s better than the audience realizing that something went wrong.

It happens. That’s life.

Likewise, in a software development team, there are moments where someone drops the ball. Sometimes it’s pre-emptive (i.e., they ask for help) and sometimes it’s not (i.e., a user finds the bug).

I feel that as a team member, it is my job — nay, my duty! — to be supportive of my colleagues. If they need assistance and I can provide it, I owe it to the team to do my best. If I can’t provide it for whatever reason, then I should do my best to point them in the right direction.

I do this on a daily basis, and I think my team is stronger for it. I may not get as much done personally, but the entire team benefits. If my actions can help Ops deal with customers more smoothly, help Sales close deals faster, help Marketing find leads to email, help Engineering produce better, more consistent, more reliable code, then we as a team are Getting Shit Done.

My advice to anyone out there, regardless of your job title, is to put yourself in a position of support. You have your own duties, and they may be great, but how can you also make sure that your team does a great job? How can you position yourself so that when someone else drops the ball, you can help them get it back in the air again?

That’s my secret to success. Good luck. :)

TL;DR: Helping others Get Shit Done is just as important as getting shit done yourself.