 Hi, good morning. I'm assuming this microphone is on. Yay, OK, hi. Welcome to this special event. I don't have anybody, a Chinese translator, talking over me, so you'll miss that part. Hi, thanks for letting me come and talk to y'all. In case you were wondering, I am totally a legit Pony fan, but not necessarily a Brony. But I can tell you that my favorite Pony is cheese sandwich. And if you know that reference, let's hang out. And just watch My Little Pony all day. So before I start, I wanted to tell you guys a quick story. I came home recently to find this car parked in my driveway. And this doesn't really happen to me very often out in the suburbs, so I took notice of a couple odd things about this particular car. So this is like a real thing, right? Cat, Sultan, cat behavior expert. So it's like a meat-cute device from a movie, right? I was expecting Meg Ryan to stumble out and bump into Tom Hanks and be like, oh, I'm sorry. Anyway. And then there's a QR code on it for whatever confluence there is of people who are in need of cat salting and have an Android phone, which is probably pretty high actually. But this is real, right? This is a cat expert. There's some cat emergency near my house that necessitated parking in my driveway. They can't be bothered to check that they're at the right house or whatever. So I realized what a sweet gig that is is like ghostbusters for cats. So hi, I'm Brandon Hayes. I am a cat Sultan. I decided that that's what I want to do with my life. And I work at frontside.io. We build client-side applications, mostly in Ember.js. So I've been doing JavaScript full time for like a year. But Ruby was my first language and will always be my first love. So why is some laps Rubyist sitting in front of you, standing in front of you, taking a half an hour of your precious life away from you? To sit here and talk about sea extensions, like that sounds exciting, right? To talk about robots, that could be a little more fun. You might also accurately predict that there will be a sprinkling of ponies throughout. Rainbow Dash, I want to believe that I'm a Rainbow Dash, but I'm really more of a Twilight Sparkle. It's true. Yeah, I am a little. I guess that would actually, that's a compliment, thank you. Princess Celestia is awesome. So as much as I love all those things, this talk is actually more personal than that. It's about burnout. And it starts with my burnout. But maybe it's your burnout, too. So let's see if any of this sounds familiar to you. I learned to program five years ago. And I became insanely obsessed with learning to program and developing software. Anybody who knew me would tell you that. And I just lit on fire about this thing. Nights, weekends, just pouring everything, every spare moment into practicing this. And every book I read was about programming. This was my new all-consuming hobby. And then after some time practicing this stuff for a couple of years, it was my new job. Suddenly, this is my career, too, which is like, wow, I'm getting paid to write code. This doesn't even make sense. I don't know what I'm doing, but people pay me to do this. Can't believe people still get paid to do this. It's crazy. So I started running a company recently in the last year with some of my closest friends. So living the dream, right? And I started noticing my passion was waning. I started feeling like I'm running out of steam. It doesn't make any sense to me. I wasn't even sure 100% that I loved programming anymore. Like, what happened? Was I in the wrong career? Should I have just left it as a hobby? So I turned to the high priest of the church of computerology. They gave me a programmer audit and hooked me up to the program meter. And they told me that I had less than 100% test coverage and that my code wasn't clean. It was dirty. I didn't know what that meant, but they told me it was dirty. I knew that was bad. And it wasn't precision-crafted out of machined aluminium or whatever. But I could buy some books and methodologies to fix it, right? So hey, the trick is you just got to be professional, everybody. Just be professional all the time about everything. So instead of taking their advice, I just fretted, right? I practiced creative avoidance. I found other things to do. And I worried that I'd lost any ability that I'd ever had to program if I'd ever actually even had any ability. So maybe my taste for coding was broken and my career was over as quickly as it started. So the thing is, I fear these things about myself, but I don't necessarily actually believe them because I can look at empirical evidence around me and realize this is probably a temporary state even if it does suck a lot. So all right, what the heck is wrong with me? Maybe I pushed too hard for too long. Maybe I was working on the wrong stuff at the time. But the fact is it's likely this idea of this thing that you love being turned into a career and ground into something that you now have to do. And it was starting to press down on me. And it became too exhausted to fight off the demons that tell me I can't do something. So how do you fight those demons? How do you slay them? What can we do about this? Well, I'll tell you what I typically do. I just rub some work on it, rub some more work on that burnout. It will be fine. I was never accused of being a workaholic before. I was pretty lazy before becoming a programmer and now I get accused of being a workaholic all the time mostly by my wife who is great. That's doubly true now in running a business as well. And for some reason, rubbing more work on it, it actually temporarily does feel like it. Here's a pain for a second, but then it delays and magnifies the cost associated with it. So then I just seized up. I don't know if you've done this before where I think seized up and every time I look at code I'd be like, can't touch code. It gave me anxiety. I couldn't work on my side projects anymore. I started distracting myself with stuff rather than creating things. I watched a lot of West Wing. I got back into video games. So it wasn't all bad, obviously. So the answer is actually really simple but it's also extremely difficult. So especially when you think you have to work or the demon dogs will catch you and eat you. But you just have to cut it out and play a little. I don't know if you guys are noticing a theme today that the idea is you have to stop and play and ship the thing that you played. So it's actually the most crucial component to overcoming burnout is shipping your play project. So here's, as an aside, one weird trick. If you want to become a high priest of computerology I've noticed something that seems to work for them and it appears to be a key in basking in the warming glow of their ranks. And that's the coin and acronym. So if you guys can coin an acronym, you're set. If it's good, good acronyms get you big shot book deals, big conference like O'Reilly conference keynotes and stuff. So obviously I hope I've got a good one here. It's Hips Cafe. It may not be particularly memorable but the secret to overcoming burnout is all outlined in my Hips Cafe plan. And you might be asking yourself at this point like was this not like a C extension talk? But hear me out for just like two more minutes. So the acronym itself is a mnemonic device but let me give you another one because it's kind of an awkward acronym. Let's think of an Elvis-themed diner as if all diners aren't already Elvis-themed. All right, so the secret is again, play until you ship. You hit burnout, inspiration pernicious, playtime, steal knowledge, and we'll build our C extension primarily in the steal knowledge part. But this is actually a framework to play in a way that results in shipping. So we've already talked about the hit burnout stage but acknowledging it is actually an important step. And if you haven't hit this, man bless you. If you never have it in your life, I'm so glad for you but if you do, you have to stop and acknowledge it and stop, stop working for a minute. Just stop. And the next step is really organic. Finding an inspiration purchase is just something that catches your fancy. For some it's finding a book about a new programming language or picking up closure script. For others it's a magazine of knitting patterns or whatever but it's anything that inspires you to want to play and make something. For me, it was this cool Kickstarter I saw. It just seemed neat, my kid loves Legos, I love Legos. It seemed like enough DIY to be easy to get into. So basically shut up and take my money, right? It's built on the Raspberry Pi which is simple, cheap, super amazing. It's got a whole computer on board so you can bring your own programming language to it. And somebody else is writing the drivers for the Raspberry Pi to do Lego stuff so I could actually program it. And I wanted a robot. I had dreams for this robot. Like anybody, I want this robot to solve, I want this robot to solve all of my ketchup related problems in my life. Or deliver tacos or something, right? Draw pictures or something. So unlike a lot of Kickstarter's this thing actually shipped and now we have a cool shiny toy to play with. So what do we do with it? Well let's, you know, we SSH in and talk to it for a minute. And then I went down this crazy rabbit hole of SD card cloning, I didn't used to do that. Wireless drivers on Raspberry and Linux. But the thing is it was actually a blast shaving these Yaks. And it's because when it's a fun project of your own shaving Yaks actually is like, hmm, this is kind of fun, I don't know why. It's more fun that way. And the info is online and you eventually have a computer that works. So let's write this thing in the library that it comes with. It comes with a simple C library and some examples to get you started. I'm not a C person from like ever. I've never written a line of C in my life, but like, hey, you know, might as well start now. So we crack our knuckles and let's get going. All right, so their library that they provide with it is ugly, but it's usable. It's arcane, kind of yucky. The cool thing about programming is you can copy, paste, ship it. Copy, paste, ship it. That's a cool programming life hack. That never backfires. So I got Hello World going. I even got the motors to spin on the robot. I was like, wow, the motors spun, you know? But then what, right? I've ever gotten started on something and you don't know kind of what to do next. You do as far as the examples carry you and then you don't know how to synthesize this information. And I was especially troubled by this because you know what writing C feels like? At least for me. It's like trying to swim with a straightjacket on, man. It's not fun to extend. It's painful to recompile on every step. This is a pretty crummy feedback loop. Like, I know Ruby. Why can't I just use Ruby for this? I could be driving an F1 car and I'm sitting in this little Shrine or Go car. Beep, beep. So my theory is this is actually an appropriate place to be stuck. Shipping typically, if you're on a hobby project, shipping will typically require more of you than you actually have. More stuff than you know now. That's, you know, you're learning something. So now for me, I'm 100% stuck. But don't fret. Because that's the next step in Hipst Cafe is steal knowledge. So I need to find somebody to unstick me. And it's helpful to find somebody who's excited by the same things that you are. Some might call this mentorship. You're going to have to build your own mentorship. Anybody who is relatively new to program, to learning to program and stuff, has probably had this experience of being like, will you be my mentor? Will you be my mentor? And there are a couple of tricks that one is to ask who you can ask. You probably know somebody that knows somebody that can help you with a specific issue. And a cool way to trick people into mentoring you is like, hey, could you look at this with me for just like one second? And then they just dump weeks of their life into your project. It's the best. And it's, I don't feel guilty about that in the least because as a person now with some more experience where I can help other people, if you have some experience under your belt, you have a responsibility to open yourself up. A lot of new people don't realize that you're probably actually waiting for somebody to ask you for help for something. And if you are oversubscribed, it probably means you have enough experience and contacts that you know somebody that could help them. And your responsibility now is to play matchmaker. So I'm lucky enough to work with one of my favorite mentors. Charles Lowe started a project for fun called the Ruby Racer. And it was a toy project. He just wanted to see if he could get JavaScript and Ruby talking to each other. And he has this like brain that allows him to comprehend hard problems like that. And it also happens to be one of several C extensions that he's written. And to say that he made this possible kind of doesn't take into account that it's kind of that he really drove this for me. I could not have done this without him. He went from advisor to helper to collaborator to person actually doing it. But it was really my sherpa through this whole process. And he shared some stuff with me that I wanna share with you. He had to basically take into account that this was some total of my C extension experience. Like, hey, this thing melted. Do you wanna look at that? He's like, yeah, I guess. So he showed me a few things that I wanna share with you in building a C extension. So keeping in mind now, I'm pretty goal oriented as a person. And so I'm trying to get a robot to do stuff with Ruby. And the drivers are in C. So we have this problem and there is an obvious solution of doing it in a C extension. So I grit my teeth. It doesn't sound like my kind of thing. But I grit my teeth and I charge right in directly behind Charles. And the first thing I do is you start with a gem. When you're building a C extension, you start with a gem. The guides on this are very, very good. They're really well written. I'd never built a gem before but it's actually pretty dangerously easy. And like dangerous because you're probably, once you figure out how to do it, you release like nine gems your first week. So step two is to lay the groundwork. And I don't need to belabor this either because again, the guides for building a C extension on rubygems.org are pretty good. So we add the necessary files and folders. You tell rate compiler how to build it. You add a little bit of config to your gem spec and a couple of other standard things. The only thing that's out of the ordinary here is we have a driver that we have to talk to called wiring pie. We find it and make sure that it has a function called serial open. And then ruby is gonna handle the compile step from here on out. You're not gonna be doing any of the crazy make file stuff. Ruby will do that for you. It's really cool like that. So step three is a little counterintuitive. You gotta stop writing C, stop playing with C and decide the ruby API that you actually want. Suffice it to say that this is the API we want. It looks weird, it looks ugly. We'll get into why in a second. But the question is how do you reach into C to pluck its strings with ruby? How do we call brick pie setup from ruby? It should look pretty familiar. You know you have a namespace, you have a module and a sub module and a setup method. So we start with this really small proof of concept. We just wanna execute this code that we know was gonna return a zero status code. We just want it to run the setup function return zero. So let's unpack this for a second. We wanna include the ruby C library, the C dependencies for ruby and your own C code. The ruby stuff is really cool by the way. If you've never looked at ruby.h, which if you're mostly a sane person, you probably haven't. But it's actually really neat. It has tons of helper methods. It's basically a DSL for building ruby in C. The next thing that we need to do is run this init method. The only thing you need to know about it is that it's magical. Bootstraps our code, don't worry about it, it's magic. Next we define our top level module. So we're actually writing module brick pie here and we're defining the native module underneath it. What this does here is this calls a C function named call brick pie setup with no arguments and we'll write that next. All right, so it takes no ruby arguments. So now we're gonna write the wrapper function. This actually calls the original C function. It returns a result from C. So here's the wrapper function. Here's the original C function. And then we have to do this crazy thing. Oh, sorry. We have to do this crazy thing to change the C into a ruby type. So we'll explain a little more about this. But what the heck is this thing right here? This first argument, this magic value self thing. Because we just said there are no arguments. So why is there an argument in this thing? Well, this value is magical and it allows your C to actually throw some elbows around because C is strongly typed. It throws its elbows around and creates a little space so that you can pass ruby objects around. This actually refers to the ruby object it's working with. And so in ruby there's zero arguments but the first argument of any ruby wrapper is to pass the ruby object in. All right, so now we just need to build the gem and test it out. And what happens next may surprise you. So this lady is experimenting with cooking without nonstick pans. May I recommend not doing that? So yeah, don't do it. So this is gonna blow up a few times on you. You're gonna work dependencies. I was pretty surprising the scale of the problem compared to the mistake that you made. Suddenly seg faults are your own dang fault. In my case I was passing a wrong argument type to an array lookup and it basically melted my computer and I had to buy a new one. The stack traces are actually pretty helpful nowadays so please use them. And so now the process, like I don't know if you have the test driven development cycle. I don't know if this is related but it's build run explode, build run explode. I think that's like red green refactor. And then suddenly, holy crap, like the first time it actually works, you almost don't believe it. But that's the API we actually wanted up front. So let me get this straight though. The Ruby file is empty. We're running Ruby, Ruby's empty. We haven't written any Ruby yet. So where did the Ruby come from? We actually have written Ruby. This is it. What we just did here was we wrote Ruby. So we just wrote Ruby in C. Yeah, how do you think Matt does it? Homeboy writes Ruby in C all day. How do you think Ruby does it? If you pull up the hood or the bonnet, if you're from somewhere else or the boot, I actually don't know. Ruby is calling the functions you just used. It's actually, you just, that's what Ruby does. It writes Ruby the way that we did. We just kind of dove down at a little bit lower level. So the crazy thing is we've actually already climbed the tallest hill. Now we've got some of the C code wrapped. It's compiling, it's returning a good status code from the init method. Ruby and C are like total best buds now. So now we just need to keep rolling on that. Let's keep wrapping more and more of that API and see if we can get the motors to start and stop. So part one is wrapping the rest of the API that we need. And that can be kind of tricky depending on what you have access to. Where do you even know how to, where do you start? Well, without example code or good API docs, I'm not sure how you would do that. I'm not sure what to tell you because you need good docs. But most stuff in our case is not documented but it does have example code we can work from. So we have API examples. So here's some beautiful, like is that gorgeous or what? Who doesn't wanna program in that all day? So I know Ruby and I know JavaScript and if I squinted that it almost looks like programming. It's a pretty verbose and there's a lot of setup in here. But we're gonna use that as like a decoder ring to decipher the source code to say, hey, here's the stuff that I know I need to call in order to make the robot go. And here is how I have, here are the C functions I need to wrap to make that happen. So it's again, it's really verbose and you're gonna have to resist the temptation to clean it up for right now. All right, so it's kind of weird to talk about a C extension style guide because the C code here is hideous. The C extensions are kind of a wild west but the result is building a C extension. And this can port over to other styles of programming whenever you're wrapping something that's horrifying. I don't know if that's a word but the result is building a C extension in a way that you can set it and forget it. All right, so how do we get to know how to do this? Well, the documentation is pretty sparse on C extensions, not super current. So, and we know the hard one knowledge is the best knowledge. Especially when you can steal that hard one knowledge from the person who want it. And this is a great book actually. If you ever have to liberate a POW camp in Vietnam, I highly recommend you check this out. So this is all hard one knowledge by me about how to do C extensions. I'm lying to you. I totally stole this from Charles. So the first step is that contours of the Ruby API should mirror the C API as closely as possible. Write down to camel casing things using parins in your function calls. At the bottom of the Ruby API, it should feel like you're right next to the C. The next step down is logically C. And everything starts at the gem name by convention. So we sub namespace native on that to sandbox all of our native code. And we can add more namespaces as needed. For example, everything here is namespaced under the, everything here is namespaced under the brick pie module. And the C struct here is actually doing a lot of heavy lifting in the C library. So we want to mirror that closely. So the C struct has a thing called motor speed under native, so we under brick pie. So we want to mirror that so that we've got one too. We're going to mirror it with module namespacing. And when we write our C helpers, it can be kind of hard to tell them from the actual C functions you're calling, so it's really helpful to namespace them. All right, so now let's take all the things that we've done and put them together into something just very slightly more complex like an array setter. So the first thing that we'll do is we will define a namespaced module for a sensor type under native. So we'll create a Ruby method to set an array element. So if that looks familiar, if you've ever written an array setter or hash setter in Ruby. And just like if you were defining this in Ruby, it takes key and value arguments. All right, so then we write the wrapper code that this calls up to. And these are going to be Ruby types. So the first thing, obviously, you always pass cell first. But, and we're going to pass the key and value from the thing that we talked about earlier for the setter. So you pass key and value. And then you have to cast this fixed num type in Ruby because this is coming in Ruby now. We've got to change it to a C int. And then Ruby kind of expects this value to be passed. Ruby, the rules in Ruby are you have to pass value as a return from a setter. So great, let's not break Ruby please because we see what happens. It's not good. All right, but that's literally it. You just do this again and again. And we're only wrapping a few types. So tell me if this looks repetitive to you. Modules, submodules, singleton method, array getters and setters, and a whole bunch of constants. So this repetition is actually really good because I know how to do stuff a bunch of times. So then we can, the other reason it's good is it means that you're pushing the C code up against the edge of the Ruby API. You have a Ruby API that's mapping all the borders of the C code all the way around. And then we can stuff the C inside a box, put it inside another box, put it in a vault, and put it inside a volcano. And never ever talk about it again. All right, hang on a second. How do we know all these crazy methods? It looks super arcane. I'll tell you what, I didn't, I cheated. And that's the next step in Hips Cafe, is cheat to win. All right, I love Karate Kid, but I have this like mental fanfic of a version with Johnny, starting Johnny. And it's like, you know the middle thing where it's like, you're the best around and they do the like the whole training montage or whatever. Well, I like Johnny, I want Johnny's one. And he has a training montage that's like, cheat to win, go ahead and cheat. Working hard for chumps. All right, it's a work in progress. But as Charles, I literally sing that every time. Like Charles is like, what should we do next? I'm like, cheat to win, Charles. And these are wise words from a wise man. I'll read them to you. Why should the race always be to the swift or the jumbled, to the quick-witted? Should they be allowed to win merely because of the gifts God gave them? Well, I say, cheating is the gift man gives himself. So we should probably at this point clarify my definition of cheating. A lot of people call this stuff life hacks, but I think cheating sounds cooler. Also, this life cheat to reheat pizza is super amazing. And stealing knowledge is often called cheating, but it's in both good and bad ways. So cheat sheets are a thing that we talk about. It's even encouraged. Cheating moves humanity forward. When we talk about standing on the shoulders of giants, we're talking about building on each other's knowledge and cheating by not having to find everything out ourselves. So my favorite form of cheating is to list the help of smart friends. All right, so with this knowledge and a whole bunch of cheating, we did it. We wrapped our C class completely. The native module is inside a black box and we shouldn't really need to touch it very often. And so let us never speak of it ever again. All right, so the hard part now is getting the Ruby API usable. Like, because we could just use it as is, right? It drives the motors. That's the point of the native module is that it looks just like the original C. If you look at this in compare to the original C that was there, it looks the same, but it's not really meant for human consumption. The cool thing is something amazing at this point happens. The motor spin. Charles and I were at BowConf at RailsConf this year and we were like, what? This is like, when you get a motor to spin on a robot in Ruby, like the dumbest thing just happened, but it was so amazing to us. Like any other person would have looked at that and been like a sixth grader did do that yesterday, you know, but for us it was like the most amazing accomplishment of our lives. So incidentally, Taco Cat is a palindrome. Think about it. So the first real Ruby layer of abstraction we're dropping in now. Let there be no doubt. This code is terrible software, but I need to tell you and confess something to you that could end my career. And that is I have a passion for writing terrible software. And I kind of hope you do too, because if you can't, how do you know how to have fun? How do you start anything without a paralyzing fear of not being perfect? This was actually a really big obstacle for me in learning to program and overcoming it was key to leveling up as a developer. So I do love to terrible code. I love writing it, and I love shipping, but I don't love shipping terrible code. And this library is not actually shipable in its current state, but we're cheat commandos. So we're gonna cheat some more. Hope you guys like cheating. So you can look at this and you can see cheating, but it's not as bad as it was before. There are no tests, sure. It's quick and dirty, sure, but it does provide a nice usable API for somebody who wants to make a robot do stuff. It's imperative. It's not very flexible. It doesn't do a ton of stuff, but for some value of robot, it gets the job done. Ship it. I think it's enough to slap a tag on it and ship it. Let's do it. All right. And then I don't know if you've ever released a gem before, but I'm pretty relaxed on shipping this thing because first off, there's no users. It's really awesome to ship apps for no users because where's the pressure? No pressure. And it's one step. RakeRelease is a miracle. It's amazing. I actually spent weeks looking for the original author of RakeRelease, trying to acknowledge them. I believe it was originally written by Ryan Davis. So thanks, Ryan, for a really cool thing. It shaves about nine of the hairiest yaks in releasing gems. So after installing the real-life gem now that's released to rubygems.org, and that was my first gem ever, which I was excited about, I was able to wire up a remote control in like 45 minutes of hacking on a quick script. And for me, that's a successful first consumption of an API. So the next step in Hips Cafe is to actually, you have to go back in a tone for the cheating that's now caught up with us because it's hard to get the robot to do anything more than just spin the motors in one direction or another. So let's see what we can do to improve it. There's still no tests, but it's a more capable robotics library. And accommodating more use cases is important to us, and it's doing that, and it's a little nicer on the API side. It's inspired by some of the dynamic JavaScript libraries we use, we love Ember a lot. It has some stuff kind of from React in it. And it can do multiple things at once in a while. It can set up behaviors and rules, and it can handle things like either analog input or incorporating feedback from sensors. It's definitely still a work in progress, but we're working on some cool stuff like a JavaScript-inspired, thenable, promises type API. Who knows where it'll go, we might throw it away, but it's really fun. This is still fun to work on six months later. So we started this and shipped it because I just wanted to see what it would do, but now let's see what it can do. It's a flippin' robot made out of building blocks, so it can do all kinds of crazy stuff. A particularly insightful friend told me that I seem to have the most fun when I'm teaching other people. So this was my toy, but I started seeing my kid get psyched about it, and it made me wonder, what if this could be a way to get kids excited about code? What if kids could produce a program in a simple, logo-like syntax and draw cool pictures with it? It's not perfect, but it does function, and my kid thinks it's freakin' awesome. And we look at this guy. It's improving, but I'm proud of it. I'm gonna put this picture up on my giant fridge. Art may not sound like the most practical use for robots, but I'm excited and inspired by seeing other people do stuff with code and art together, and it feels like a world of endless possibilities. Okay, great, we shipped it, congratulations. It's time to reward ourselves for shipping. The philosopher Jacques says that we are conditioned by Coke's marketing to think that Coca-Cola is a reward. And you know what I say to that? It is, he's right. Delicious, ice-cold, refreshing conditioning, and you can relax on the beach now. We shipped it, and sip a Coke, let your book deals and thought-leader checks roll in, I'm guessing, I don't know. Open source maintainers, please back me up on this. All right, the problem now is that people maybe start using it, and there's a hitch in the plan here. You know that your code has horrible secrets in it, and other people are going to bump into them. And now your fun project is a job. So congratulations, you have now completed a circuit back to burnout, but you hope that it's a virtuous cycle, that you've done something, and things are a little better now, and you also meet interesting people and delegate to them. So here's an interesting question. How did I manage to pour dozens of hours into learning sea extensions while burned out? Moreover, how did that tow me out, fix me up, and get me back on the road? How it works is mysterious, but the trick is to ship, to play until you ship. Burnout is because you forgot you love something. And playing is how you get back into the courtship phase. It's kind of like date night for your love of programming. I don't think it's a coincidence that children live in a world of play and infinite possibilities. My little guy's not too bright, he's getting smarter, and it's how fun is it to participate in that. Share your play projects, please. Jin Schiffer did 8-Bit Art, which is amazing. Anna Piranha did Meet Spaces, which is changing the way people communicate. And most of all, to me, why shared his art, and it changed my life, because it made me realize I could be a coder, even though I was a crazy, like, arty type. So the world needs you to stop and to play and to ship your play projects and share what you've learned. That makes you immune to the computerologists of the world. Thank you, go ship some amazing stuff.