Talks

The Rubyist's Illustrated Rust Adventure Survival Guide

The Rubyist's Illustrated Rust Adventure Survival Guide by Liz Baillie

Programming is an adventure, often more harrowing than it has to be. If you're more used to higher-level languages like Ruby or JavaScript, learning a lower-level language like Rust can feel like an impossible journey that leaves you wishing for a well-written and heavily illustrated field guide. Good news! I have already gone down this road and am now prepared to share my adventure with you. Luckily, I was able to capture much of the flora and fauna of Rustlandia with my primitive pictorial devices (paper and pen).

GoRuCo 2017

00:00:16.920 So, the full title of this talk, which does not actually fit on most CFP submission forms, is "The Illustrated Adventure Survival Guide for Noura Stations and Natives of Rubyville," with apologies to Why the Lucky Stiff. How many of you are familiar with Why the Lucky Stiff's work? Awesome! That's great! That's the most people I've seen in a room for this talk, and I've given it about ten times.
00:00:34.540 If you are familiar, which many of you are, you’ll recognize a few things in this talk. If you're not, I would strongly recommend looking up Why the Lucky Stiff. He was a Rubyist who did a lot of really interesting work and was a big reason I got into programming. This whole talk is kind of, well, half of it is an homage to Why the Lucky Stiff's poignant guide to Ruby, which I believe you can find online for free if you want to check it out.
00:01:09.520 Anyway, welcome! I really have to commend you. It took a lot of courage to sign up for this mission. This adventure we're about to embark on is not for the weak or the faint of heart. So, if any of you are pregnant or nursing or suffer from any kind of heart condition, or if your doctor has advised against eating spicy foods, I ask that you consider consulting your physician, spiritual adviser, psychic medium, or your nosy next-door neighbor before accompanying me on this journey.
00:01:17.170 While we wait to board the ship, some of you might want to know a little bit about me, your guide, before moving forward with this seafaring journey. And I get it; I understand I don’t look quite like a seasoned ship’s captain, and you're right—I’m not! I’m Liz. I used to be a cartoonist. I drew comic books, went to art school, and created a few graphic novels. A few years ago, I learned to code. I went to the Flatiron School in New York and started working in web development.
00:01:47.409 Nowadays, I work at Tilda in Portland, Oregon. Mainly, I work on our product Skylight, which is an application that helps developers working in Rails or other Ruby-based frameworks to optimize their apps. We also use Rust, which is a big part of why I started learning Rust in the first place. So, before we get on the ship, I’ll show you a map of where we’ll be going. Right now, our ship is docked at the port of JavaScript, just off the coast of Rubyville. We’ll be sailing the Seas of Chunky Bacon and should be landing at the Cargo Bay of Rustlandia in no time.
00:02:22.560 So, let’s get onboard! Please take your seats. No standing, no eating or drinking, but most importantly, no staring at the ship captain. Aye! He’s really sensitive about it! So, say goodbye to your loved ones, and off we go! Sailing, sailing over the bounding main—this is a song about sailing. I don't know the rest of the words.
00:02:54.870 If you all look out your windows to the west, you’ll notice a beautiful sight: some foliage that’s native to Rubyville and abstract syntax trees. Its nodes are particularly lovely this time of year! You’re probably used to seeing these if you’re from Rubyville; they tend to sprout any time some code gets thrown into the interpreter just before it gets turned into bytecode so the Ruby virtual machine can run it. As you might already know, Ruby is an interpreted language, so this is more or less what you're used to if you're a Rubeus.
00:03:36.360 But in Rustlandia, we have to remember to compile our code before we can run it; otherwise, it won’t work. So, when we get there, just remember to keep `cargo build` and `cargo run`. They will come in handy when we reach the shore and start trying to chat up the locals. If you try to just run your code directly like you did in Ruby, though, they won't know what you're talking about!
00:04:03.320 On the way out, you'll notice a big pile of mains; don’t forget to take one! You’ll need to put all the code that gets run for your program inside of main unless you’re building a library, but we’re not there just yet. So, very important! Alright everybody, off the ship! Here we are. Welcome to Rustlandia!
00:04:14.190 Yeah, let's check out the town! Remember, things move a lot faster here, so be on your toes. Check it out! It's a second-hand proof of concept. Let’s go inside! You're probably used to not giving much thought to memory back in Ruby. However, before I came to Rustlandia, I had heard of the stack and the heap, but I had seen it as something I decided is memory, but I didn’t really understand it!
00:04:35.420 So, watch how things work at the bar. People come in, and they give their programs to the bartender, and she compiles and runs them. Let’s say someone wants a fancy whiskey and a cheap whiskey. The good stuff is fancy, so we put that in a box and store it on the heap because we want it to stick around for a while, even though it's high up and a bit slower to get to. Most things in Rust are stored on the stack unless you specify otherwise, which is why we had to put the fancy whiskey in a box to store it on a heap. So when we run this program, the good whiskey gets a spot on the heap at the far end of our available memory, and we put a pointer on the stack that points to that spot.
00:05:31.810 On the stack, we put the cheap stuff—in this case, it is Old Grain Grandad, which is a very terrible bourbon, if you didn't know. The cheap stuff gets served up first because it’s on top, and then we have the pointer to the fancy stuff, which the bartender has to go way up to the top of the heap to get. All that sea travel made me hungry! I think let's check out one of the local eateries! I've heard good things about this one; it's called Café Destruct!
00:06:30.360 Oh, sir, I can't quite read this menu! We have to... seeing things like this, there’s a defined class and the instance method, so that class is defined with a simple `def` and they end with the word `end`. Instead, I feel these strange new things like structs and impulses. What's this all about?
00:06:58.080 I’m sorry, madam! I know this isn't something you’re used to back in Rubyville, but we here in Rustlandia, uh, we have no class! No class! I can’t believe it! This is terrible! How are we going to get along without class? It’s the one thing separating us from the animals. Don’t worry, don’t worry at all! You can still get what you need here! Here’s the Chunky Bacon construct. This is where we define all the attributes we expect out of it: flavor, chalkiness, price, etc. So then I can just do something like this, and I’ll be all set. No, no, my good lady! For that, you’ll need to write an implementation of Chunky Bacon! If you want a new instance of Chunky Bacon, you’ll have to write a new method yourself; it doesn’t just happen automatically.
00:08:21.560 Well then, very good! I’ll have a salad, and now a word from our sponsors. Hey, MEK! Me? Yeah, you there! You wanna try some Rust? You mean the iron oxide produced as a result of a redox reaction of iron and oxygen in the presence of moisture? What have you been reading? Wikipedia? No, not that! Restful Rust, my friend! Oh yeah, that cool means—the systems programming language all the kids at school are talking about! The very same!
00:09:06.440 Well, what about it? Do you like abstraction without overhead? I don’t know! How about concurrency without data races? I think, what about memory safety without garbage collection? That sounds good! I really don’t do it all, Rust! Welcome to Mutability Lake! It’s a lovely day, and so many of us distinguished townspeople are out sailing their toy ships! Some are fancier than others, some are mutable, some aren’t! This one here is nice; this one’s not mutable, so we can’t change anything about it. But I can pick it up and show it to you—look how nice! But if we try to change anything about it, hey, you can’t do that! The compiler is yelling at us, so we know we can’t change this boat; it’s immutable! Let's try another one! Let's look back—what other ships are out there?
00:10:30.520 Cool! This one’s definitely mutable! It has a little flag that says 'me.' Let’s just make a few changes before we return it! Let’s add some wheels to this boat! Perfect! Compiler, what do you think? No? What’s the matter, compiler? You put wheels on a boat; it’s not a boat anymore; it’s a car! You said you would return a boat! You must return a boat as it is clearly illustrated here. The boat struct does not include anything about wheels. Okay, okay, I’ll take the wheels off! It looked pretty cool, though!
00:12:07.320 Let’s look for another boat in the lake! Hey, that one looks pretty cool! You like—hey! That boat doesn’t belong to you! Oh, I’m sorry, compiler! To lure this boat, I do so! Sorry! Can I borrow it? I was hoping to play with it in my bathtub. Well, will you bring it back? Of course! Go right ahead! Don’t forget this ampersand so everyone knows you’re just borrowing it! And now, a musical montage!
00:10:11.970 Hey! Thanks for returning my boat! Compiler, does everything look good to you? No! You added a tugboat! That’s not okay! But compiler, these boats are all vectors of strings! All I did was push a tugboat onto it! A tugboat is a string! The tugboat isn't yours, and neither is that boat! Yeah, that tugboat is mine! Well, what if I just punch the tugboat guy in the face and hit him with a remove? Looks like no one owns this tugboat now. You want to talk about the ownership of your boat, sir?
00:14:00.800 Sure! Let’s do it! Boat that push and pass in the tugboat—now you have one! And now another word from our sponsors. Hey kid, where did you get all that information about ownership and borrowing? Huh, that’s how we get a lot of the cool stuff I was telling you about before; you mean like when you were yelling ‘memorizers!’ card with cocaine at me? Yes! You got it! I only know Ruby, though, so these aren’t really problems I’ve had to deal with! Well, let me tell you—if you were a C programmer, you'd be really excited!
00:15:41.930 Okay, you bet! It’s okay! Can you just teach me something about Rust so the kids at school will finally think I’m cool? Sure thing, kids! Let’s try a less convoluted metaphor! Hello again travelers! Have you seen our Steam library? It’s pretty great! You can borrow just about anything as long as you return it! They even have this great big pile of books over there that don’t belong to anyone! You can just take them if you want, and then they’re yours! Every so often, people will come by with donations of books they don’t need anymore.
00:16:23.560 It’s great! If you want to borrow a book, you just need your ampersand. If you try to change the book while you're borrowing it, the compiler will yell at you, and your code won’t compile! However, if you see something you like in the free pile, you can just take it and do whatever you want with it; it's yours! Oh, you in the back, you have a question? Yes! What about if the book is an immutable reference? Great question, friend! Well, you might very well be borrowing something that's mutable, like our collection of coloring books here. You can continue coloring in them while you have them and you can return them altered! Only one person can have one out at a time, though!
00:17:56.330 We also have some exquisite corpse boats that are pretty cool! Every time someone borrows one of these, they add a little bit of themselves before bringing it back. I want to borrow the exquisite corpse boat! Me too! I want to borrow it too! No! No more than one mutable reference at a time! You can have it now, but you have to wait until the first person is done before you can borrow it! Oh man! No complaining! Do you want a day to race? Do you know? Okay then!
00:19:41.960 You might have noticed how clean and beautiful Rustlandia is, and yet you might have also noticed there are no garbage cans anywhere! It’s actually because of that system of borrowing and ownership that Rustlandia is able to do without garbage collection! It’s a big part of what makes everything so fast and safe here! But isn’t it annoying having the compiler yelling at you all the time? Hey, now! Don’t judge the compiler! Look, you hurt his feelings! He’s not such a bad guy! He’s just making sure everything we do is good before we run it! The compiler is our friend!
00:20:39.490 He just wants the best for us! Sure, his advice might be a little hard to understand at times, but once you get to know him, he’s really a good guy, I promise! And now, another word from our sponsors! Tonight on WRST, it’s the true story of how one statically typed programming language risked it all to figure out how to handle it when things go wrong! Being and Nothingness and error handling! Based on a true story—if everything goes right, the reactor will cool down and the city will be saved! But if something goes wrong—if this whole thing goes south! I guess I’ll just do nothing! I mean, it seems like it’s time to return an option, right? I mean, the compiler feels fine about it!
00:21:45.420 Looking good! Meanwhile, across town, the grocery store doesn’t have the mustard I like! Red alert! Red alert! Everyone pay attention to me! Shut everything down! I need my Dijon! Compiler, you agree, don’t you? Looking good! Public service announcement: just because the code compiles doesn’t mean it’s something you should do! Resulting for when something could go terribly wrong, and you need to throw an error. An option for when it’s okay to just do nothing with it! Learn it, love it!
00:23:09.650 Hey! Welcome back! Just in time for the last boat back to Rubyville! I sincerely hope you enjoyed your stay and that you visit again soon! If you want to stay a little longer, there are some very nice boxes at the heap! Otherwise, the boat is ready to board. On your way back, we do have some very nice reading material if you're interested in learning more about Rust! I strongly recommend starting with Rust by Example. This is an online book that will lead you by the hand step-by-step through many examples, explaining everything along the way.
00:23:55.490 After that, you can look at the official Rust reference documentation, which is very helpful if you’d like to try your hand at some Rust of your very own from scratch. There are many excellent exercises available at Exorcism! If you have questions, there’s the Rust Reddit and the user forums, or you can chat on one of the many channels on IRC! In preparation for the original version of this talk at RustFest last year, with some help from my boss, I’ve developed a playable text-based adventure game in both Ruby and Rust! This way, you can check out Ruby and Rust code that do similar things side by side!
00:24:57.370 I’ve written a few very little ones over the years, usually when I’m trying to learn a new language or if I’m playing with a new idea. Some of you may never have played one, but it's basically a game where everything is text! In my case, the whole game is played in your terminal like it’s the 80s! The way it works is you get a prompt, usually a sentence or two followed by a question: like, 'You are in a dark forest; you see a light in the north. You have a map. What do you do?' And then you type something like, 'Look at map,' and the computer responds with something else, and you type something else again.
00:26:10.830 So on and so forth until your character dies, and the game is over. I think nowadays, games like this are also called interactive fiction! Let’s take a quick look at the actual game I wrote to give you a better idea of what I’m talking about. Let’s see how this goes. Okay, whoa! So Ruby means gonna be okay—this won’t work out quite a bit! What is your name? My name is Liz! What would you like to do? Look around! This room contains a rare and glorious unicorn. It’s amazing! This room contains a jar of unicorn for its unicorn doctors here too! What now? Talk!
00:27:45.210 Hi! I’m a unicorn doctor! It’s pretty cool! I have a vial of unicorn blood! You want it? What now? Oh, take a vial of unicorn blood! Who doesn’t want a vial of unicorn blood? Okay, I wrote it wrong! Takes vial of unicorn blood! Maybe vial of unicorn blood has been added to your inventory and removed from the doctor’s inventory. Okay! I want to use the vial of unicorn blood! I want to know what this does! Uh, it made me invincible! It’s amazing! So great! Okay, I want to get out of here!
00:28:58.720 Oh no! It's go back and hopefully this works out!
00:29:21.230 Okay, so that’s the game! But how did I actually build it? Before writing a single line of code, I had to think about the architecture of the game! There are a million different ways I could find a structure it. In the end, I wanted something super simple, so I went with a really basic loop! It continues to ask what the player wants to do until a particular condition is met, at which point the game ends!
00:30:00.000 So in this example, which I stress is not real code, just an example of the structure I was using, we start by defining playing as true, and while playing is true, the game asks, 'What do you want to do next?' Then it parses whatever the subsequent user input is and performs an action based on that input! Like if you just say 'move north,' the player's position is changed. Maybe we output something like, 'You have moved north!' We don’t exit the loop unless the user dies or the game ends, at which point playing is redefined as false!
00:31:30.890 So what does this look like in Ruby or Rust? In Ruby, there’s a lot going on before we get to the play method, but that’s where the loop is, so that’s what I’m showing you! This is a method on the game class, which is initialized with a player, a map, and an array of rooms, and with the value of playing is true. So as long as playing remains true, the game will keep asking 'what now.'
00:32:20.750 Then I’ll parse what have you and respond to that. So, this example is ignoring a lot of other code I wrote to support this, so it doesn’t fit on the screen.
00:32:21.170 Much like the Ruby example, but for the sake of simplicity here, you can see we are creating a player, a map, and a game. And you can see that while game.playing is pretty close to what I illustrated earlier, what you can’t see is that unlike Ruby, I had to write my own new method because Rust doesn’t automatically give you anything like Ruby’s initialize and isn’t object-oriented by nature the way Ruby is! So there are no classes per se!
00:32:59.240 Otherwise, it seems pretty similar to the Ruby version—just a little more code, which is fine. So what differences did I notice in writing the game with Ruby? I felt like I could just write whatever I wanted; make something work quickly and then reorganize the code as I went. It’s really easy to have a flow like you’re just writing your ideas in your journal and you’re making things up as you go along.
00:33:39.620 But the downside of this is that it’s really easy to get caught up in that flow and forget to check things out as you go. I forget to test, forget to run every single part of the program I just wrote, which I did! I periodically run the program, and things would break without adding a whole bunch of tests after the fact, which isn’t great! I didn’t have a lot of confidence that something wouldn’t just unexpectedly fall apart at runtime because I got caught up right in the game, and I forgot to check things out as I went along!
00:35:31.580 My Rust, on the other hand, is kind of the reverse experience! Since Rust needs to be compiled before you run it, the compiler literally won't let you run the program until you fix all the stuff it doesn’t like! Not coincidentally, I have not run into any pesky random bugs in the Rust version of the game, probably because the compiler caught them before they could become a problem!
00:36:11.380 This can be super frustrating, though, when you're first learning Rust because it can be so satisfying just to see something working! You could be working for hours and see errors like this over and over, and it can easily become really disheartening if you’re new to it.
00:37:09.880 Yeah, it’s true—Rust is good! This might seem like a weird simile, but the best thing I can think of to compare Ruby and Rust in terms of my personal experience is like there are two different parenting styles. This might seem like an odd comparison, but bear with me! Ruby is like the hippie parents who let their kids do whatever they want! They don’t put a whole lot of restrictions on them because they’re like, 'You’ll figure it out, man! It’s cool! You’ll be okay in the end! I trust you!'
00:38:51.210 The downside of course is that the kids will hit all these bumps in the road along the way, like no one told them they shouldn’t walk into traffic or whatever! Rust is like those parents who are constantly trying to teach their kids what's best for them! They're a little bit strict! It's not that bad, but they're just always giving this unsolicited advice based on their own experiences. Maybe it turns out their advice was right, but it’s definitely annoying to be hearing all the time.
00:39:35.890 And just like parents, you can’t really say one way of doing things is better or worse than another! Both have their pros and cons depending on what you’re trying to do and how you prefer to work! I'm sure some of those more experienced could give a more in-depth analysis, but this is my opinion based on my limited experience just reading a simple text game!
00:40:45.440 So if you’re thinking of trying Rust or Ruby, I’m sure you’re all Ruby people anyway, or both, I say go for it! You can check out the game I built at github.com/tildeIO/learning-rust! Both versions are playable and both have kind of filler stories in them. The Ruby version’s filler game is a little more fun, though—if you can only play one of them!
00:41:21.190 Thank you for having me! I have been Liz, and I’m on Twitter at _lBailey. That’s it!
00:41:46.670 The end!