NOEL: Hello and welcome to Episode 43 of the Tech Done Right Podcast, Table XI’s podcast about building better software, careers, companies and communities. I'm Noel Rappin. In this episode, we're talking about the Ruby community and how it has extended itself outward into other languages and tools. My guests are James Edward Gray and Steve Klabnik. They both have extensive experience as Ruby developers, writers, speakers and teachers and they have both brought that expertise to other language groups. We’re going to talk both about the technical aspects of these different tools and also the cultural aspects. What does the Ruby community bring to Elixir or to Rust? But before we start the show, I have a few quick messages. Table XI is now offering training for developer and product teams. Topics include testing, refactoring Legacy JavaScript and career development. For more information, email us at Workshops@TableXI.com or hit our website at Tablexi.com/Workshops. And I haven't mentioned at the top of the show very much in the last few months but if you like the show, a review on Apple Podcast would be great and really helps other people find the show. Now, here's my conversation with Steve and James. Steve, can you say a little bit about yourself? STEVE: Hi everybody. I'm Steve. I am currently working on the Rust programming language for Mozilla and previously, I wrote a whole lot of Ruby code but it's been a little while. NOEL: And James? JAMES: I am James Gray and I go by James Edward Gray II on the internet. I also was in the Ruby community -- I'm still in the Ruby community -- but in a smaller role these days like Steve and while he's been playing around in Rust, I've been playing around in Elixir. NOEL: The reason I wanted to have you both here is that both of you were at one point, extremely prominent members of the Ruby community. You both spent a lot of time developing Ruby code and you both become... moved on is probably the wrong way to put it but Ruby is no longer exclusively what you do or even a little bit of what you do. What I want to talk about here was I feel like there is this trend of Ruby developers heading off to other tools that fill different needs for them. There is both a technical track where developers need to do something that Ruby doesn't do and so they gravitate towards certain tools and maybe away from certain other tools. Then there's a community track, where the Ruby community is somewhat opinionated and may or may not bring those opinions or some qualities to the language groups that they tend to go after. I guess I want to start with what kinds of needs did you have that made you start using languages other than Ruby for regular development? JAMES: That's a cool question. I want to hear Steve's answer. STEVE: I guess the first thing I should say is it's not because I do not like Ruby. I have a Ruby tattooed on my body. It's not going away anytime soon. Even though I don't write Ruby code at all anymore basically, it's still extremely a thing that is fond to me, fond memories. But part of the reason why I decided to kind of move on is because I felt like I had accomplished everything that I could accomplish in the Ruby world and I wasn't really growing as a person because I sort of had maxed out on understanding Ruby on Rails to such a degree and there was not really that much more to learn and therefore, I felt a little stagnant, to be honest. NOEL: So you went to Rust. What kinds of things do you learn from Rust that you didn't learn in Ruby? STEVE: Rust is a programming language, fundamentally. We are still kind of sorting out the best way to describe it because we used to talk about in certain terms and those terms are kind of meaningless. The way we're thinking about it today is like Rust is the language that empowers people to work at any level of the stack that they want to do. You can write web apps in Rust. You can also write operating systems in Rust. It was originally sponsored by Mozilla to improve Firefox by rewriting chunks of Firefox in that code and as of last year, that's now actually true but that took almost a decade but beyond Mozilla, it's being used by a ton of people in a ton of places for many, many different things but the kind of idea is the language lets you scale little up and down the stack. NOEL: Okay and so, what do you get from working that, like what itch does that scratch for you? STEVE: On a more like 'programming language nerd' answer is Rust and Ruby are in many ways, sort of diametrically opposite. I really like learning things that are significantly different from what you currently know because that means you learn a lot. One of the most obvious and huge things is Rust is incredibly, strongly, statically typed and Ruby is not, to say the least. I've gone back and forth between preferring static and dynamic typing throughout my life. I actually started with dynamic language and then moved to statically typed ones for a while and then moved back into dynamic ones. This is like a constant ping-pong back and forth but by the time I was at the end of my Ruby time, I was really, really into the dynamically typed mindset, so getting into the statically typed one was a very, very huge difference. Another one is that Rust does not have a garbage collector or a runtime and so, it exposes sort of these low level details significantly more than Ruby does. Ruby is trying to make your code look as nice as possible and we try to make Rust code look good but there's also other concerns that are sort of hard constraints on the design but we actually like still learn from Ruby in many ways. Our closure syntax is almost identical to Ruby's closure syntax. It's kind of interesting and our build tool is literally written by Yehuda, so in many ways, it sort of like Bundler but a little more like npm and all that kind of stuff. There's a lot of interplay between the two worlds. NOEL: Yehuda there is Yehuda Katz who used to be a core member of the Rails team and then moved on to design Ember and has also worked on Rust quite a bit. STEVE: Yup. JAMES: Awesome. I just learned that Steve and I have Ruby tattoos in common, which is amazing. STEVE: Nice. JAMES: I also have a Ruby tattoo. NOEL: Now, I feel like my love for Ruby is in question. JAMES: That's right. It is. It's in question but Steve and I also have in common that we've played with Rust, although for him, much more than me, of course. But I have played with Rust quite a bit and I love what Steve said about trying to get some new ideas and see things that are fundamentally different. That is also the reason I go to different languages and things like that and Rust in particular, was quite brain-bending for me. I'm going to mention some things I thought were cool about it, that really made me think about things in a different way. If Steve wants to elaborate on any of those because I will surely get parts a bit wrong then he absolutely can. But what Steve was talking about, about having no garbage collection, Rust has this memory model, I guess is what I would call it called "ownership" and that is just a super cool concept. That took me a fair bit to get my brain around but after I did, I looked at computing completely differently because I can remember back to models what does Perl's old garbage collection called 'mark and sweep.' STEVE: It's Ruby's, too, at least until very recently. NOEL: Garbage collection is the process by which the runtime system itself clears unused memory. Mark and sweep is an algorithm for doing that, where memory that is in use is tagged by the runtime and periodically the runtime goes through and clears out memory that it does not have the mark. So, Rust's ownership model is different than that. JAMES: Yes, actually I'm glad you said that, Noel because you made me realize, I did say the wrong thing. Mark and sweep is a good example in the spectrum but actually, I was thinking of reference counting, Perl's older model before that, where every time something is allocated or used, a reference is bumped up and then, when it goes out of scope, the reference is bumped down and when it hits zero, then that thing can be collected, right? NOEL: Right. In a reference counting garbage collector, when you reference a variable, its count goes up and it is susceptible to problems where circular references never get garbage collected because they never go down to zero. JAMES: Exactly and you have to take steps to avoid that. The Rust ownership model, I'm almost scared to describe this, especially with Steve on the podcast but I'm not -- STEVE: That's fine. JAMES: The Rust ownership model is that when memory is allocated that the chunk of code that allocated that memory owns it, so to speak. If you hit the end of that chunk of code, then that ownership is gone, therefore, it can be collected immediately because it's not used anymore. If you want to pass that to something else, you have to transfer ownership to that thing that you passed it to and then that thing owns it for the time period that it runs. It's super great if you've ever had to do some manual way to manage that in C, where you're allocating and freeing memory or something like that. There's just so many ways it can go horribly wrong but Rust kind of flips it on its head and makes it very explicit that way, this chunk of code owns it, then it's handed off to this other chunk of code that will be in charge now unless ownership is transferred again. You always know exactly where something will stop being viable. Do that seem like a fair description? STEVE: Yes, you were nervous but that's a fantastic description, actually. The only other thing I would add on is that this all happens at compile time. There's no runtime component in any of this. NOEL: Right, so the Rust compiler can determine at compile time, whether a variable will be in memory based on its ownership and if it determines that it won't be, it does not let the program compile. Is that a fair way to put it? STEVE: Yeah. NOEL: I have no real Rust experience. JAMES: Which leads me to another amazing thing about Rust and if you've never seen this, it's like a wonder of modern computing that you must behold. In Ruby, there are common way examples in books where they'll make a bunch of threads, spawn a bunch of threads and they make some global counter and have all the threads try to bump a global counter like a thousand times, so then if you spawn 10 threads, they show you that the number in the end is not 10,000. In that way, you get to see that they were colliding over this variable and the problems of shared memory, right? NOEL: Yup. JAMES: If you write that same program in Rust, it will fail to compile your program because it's incorrect. NOEL: Incorrect because the shared access is not viable? JAMES: Not safe. Yeah, it's not safe. STEVE: It's more than just of shared access. It knows that it's being shared in a way that is not defined behavior. If you included a synchronization primitive, it understand that that's true and would let you compile that. If you wrap the number in a mutex, then it'll be cool. It's not that shared memory is the problem. It's shared memory without the safety aspect. NOEL: Unprotected shared memory, right? STEVE: Yeah. NOEL: I feel like I still need to be like definer guy. STEVE: It's very helpful. NOEL: A mutex is a structure that you place around a variable that might be shared which effectively limits access to that variable to one other thread at a time. STEVE: Yeah. The name comes from mutual exclusion. The idea is that only one thing can access it at a given time. JAMES: But seriously, the first time you see a Rust program not compile because it's like, "You know what? You really don't want to do that. You're shooting yourself in your foot and I'm going to say it here." It's amazing. NOEL: I feel like I have done some of the other languages that we're going to talk about but have not done Rust really at all. How much time do you spend just arguing with the compiler, trying to get it to compile things? What happens in that case? You’ve put together this system, you've set shared access to a thread and it doesn't compile and presumably, it tells you a reason why it doesn't compile. What does it say to you? STEVE: The two components of this, the first one is this that when you start programming in Rust, this happens a lot. You spend a lot of time figuring out like, "Oh, yeah. The compiler said this is wrong. Why is it wrong?" and we try to make good error messages to make that a reasonable experience but eventually, a lot of people describe it is as like within two weeks to a month or two, all of a sudden you realize, "Wait a minute. I haven't been struggling with this for a while," and it just kind of works. At some point, you internalize these rules in a way that ends up being purely helpful. Most of the time, when I get one of these errors, I'm like, "I know exactly what that means. I know exactly how to fix it," and it's more like a test failing than it is like a colossal struggle but at the start, it's definitely a challenge. NOEL: Yeah. I had a similar experience not with Rust but with Elm, which was the first time I had programmed in a strongly typed language in some time and Elm, James, as I'm sure you know, is known for exceptionally good compiler error messages. STEVE: We modeled ours after Elm, for that reason. NOEL: I had a similar experience where I started with it, spent a fair amount of time just sort of arguing with the compiler over like, "I know that this should be possible," but the error messages were tremendously helpful in explaining what I needed to do and then again, after a relatively short but not non-existent period of time, I saw less and less of that, so you do get acclimated to it. JAMES: I feel the same way just to kind of to pile on. I do want to say I agree about Elm's error messages and if I were to name any one language that can give a run for its money in the error message department, it's Rust. They are really good. I'm always surprised by like, Rust will often correctly intuit it what I was trying to do. It will say things like, "You've messed this up. It looks like maybe you were trying to do this. Maybe you should go and read this webpage to explain how this works," or whatever. It's amazing. NOEL: One thing I like about the Elm's error messages is they will sometimes say, "I found this error here, but it often means that the real error is like the previous statement, so you should look there too", which is very helpful. STEVE: One other Rust thing that on that point though. One thing we're introducing soon, James, is a tool that will take what the compiler thinks your code should be and you can run a mode that will just apply it and change your code for you automatically. JAMES: That's so awesome. STEVE: And we sort of have a confidence level, so only ones that we're pretty confident will actually fix your code that will give you and the one that's not sure about it, won't. That's kind of like a fun thing we're working on. JAMES: That's super cool and you can see by what Steve just said there that a lot of thinking goes into Rust error messages and it's extremely obvious when you get them. I pretty much agree with what has Steve said earlier when I first started trying to program Rust. For me, it was absolutely the ownership model and almost every error I got was related to not understanding ownership and how it works but then after a certain time period, you feel like you get over that hump and you're like, "Oh I understand what this means, when it's saying this to me," you know what to do about it. NOEL: It does feel like Ruby developers move towards other tools that seem to have a similar level of respect for the developers day-to-day happiness that they have, really good error messages or really nice syntax or something that is designed really with the developer experience in mind. STEVE: Part of it for Rust is that frankly, nobody tries to make a language. that's hard to learn, but Rust has these low level constraints on its design that we can't possibly break and so those are more important than the learnability. Rust is kind of just inherently a little difficult to learn and so, we knew that if we want to be able to use it, we needed to give them as much help as possible to get over that hump as quickly as possible. There have a number of features that are in the pipeline or have recently landed, that are all aimed at how do we drop the learning curve while not still giving up on the actual constraints of the design that we need to have. For us, more than many other languages, it's like an existential threat. If Rust was just too hard to learn or had terrible error messages, the language would die and so, beyond even just the fact that we also program in Rust and want to be nice, it's extremely important for the language to actually be successful in the first place. NOEL: And they have people like Steve Klabnik writing books about the Rust programming language to help bring people onboard as well. STEVE: Yeah. We're super lucky to have a bunch of different books now and they're all pretty good. JAMES: Documentation, too. Documentation is really good. STEVE: Thanks. JAMES: To kind of expand on what Steve was saying there about Rust has this known weightiness that has to compensate for, which leads to great error messages. I kind of feel like that is the reason that people end up looking at different languages and things and I'm going to take this, probably on a totally unexpected direction but I have a young daughter and we spend some time playing around on the computer together. One of the things I play with a lot now is Scratch. NOEL: Scratch is outstanding. JAMES: Yeah. STEVE: Yeah. NOEL: I've been aware of the Scratch project for a super long time because I was a grad student in educational technology when its predecessors were being developed. Scratch comes out of the MIT Media Lab. It is a graphical programming language, where you create programs by dragging components together. Its long term predecessors are Logo and StarLogo and a couple of other things that are probably not of interest of you but it's a long running MIT media project that is very cool internet programming runtime. JAMES: Yeah. It's fantastic and my daughter and I, we have this book of Scratch projects that we worked through. It has us do all these things and then we played around with it and I have to tell you that Scratch is a programming language that absolutely everybody should go and work with it at some point because there are some things in it that none of our uber-powerful -- Ruby, Rust, Elixir included -- have and the number one feature that I would name is it's impossible to write a syntacticly invalid Scratch program. NOEL: Right because you're building it in this graphical environment and the components fit together. It's been a couple of years since I've used it but they sort of plug them in and they will only fit in syntactically correct ways. Am I getting that right? STEVE: It's like Lego. NOEL: Yeah, like Lego. I completely love that we've gone from Rust to Scratch right now. I'm tremendously happy about this. STEVE: Yeah, it's my jam. JAMES: It's great. I spend all of my days writing programs and we just talked about how, "You know, there's this period, where you and the compiler have to learn how to get along and communicate through each other so that you can understand what it's trying to tell you." And we think, you know, we're programmers. We use all these uber-powerful programming languages. The language my daughter is using makes it so you don't have to do these things. That's kind of amazing, right? NOEL: If the metric is you should learn programming languages that teach you something new about programming, I would definitely recommend that that everybody take a look at least at Scratch. It's really fun and it's really neat. JAMES: And just so people don't think, "This is like you need to Scratch. It's a kid's learning environment," and stuff like that. Actually, there are multiple things and multiple languages that "allow" you to program in a way that you cannot make a syntactically invalid programs. In game programming, it's actually becoming semi-common. There's a game creation tool kit called GameSalad that programs similar to Scratch in that you kind of drag and drop things or insert known things. There’s also another game studio called GameMaker Studio 2 and that one, you can drop into the code if you want to but it does also have this like... I don't know how you describe it, kind of a visual DSL or something that while you're using that, you can't make syntactically invalid programs and that particular program let you switch back and forth between the two. There are people out there, programming in their job, making games and selling them for money that used programming languages where they cannot write syntactically invalid programs. That's pretty awesome, I would say. NOEL: Many, many years ago, I worked in Prograph, which is a language that has basically died but was a graphic language, the Prograph programs looked more or less like flow charts, object oriented, dynamically scoped, dynamically typed. It also had the feature because you were dragging boxes together that it was, I don't think impossible but it was extremely difficult to come up with an actual syntax error in it. It died for other reasons but I miss it a lot. That was fun. JAMES: It's great to have this options and it makes me think about programming differently. Nowadays, when I'm programming, I think, "Why are we spending all these time editing text files." Emacs and Vim are amazing and the reason is that they have to be because we do this horrible thing all the time of translating text to code and I don't know why we don't have more tools that basically allow us to edit the abstract syntax tree directly, right? STEVE: There's lots of reasons. One of the problems is that most programming language's AST's are just not stable at all. NOEL: What we're talking about here is AST -- abstract syntax tree -- and that is the internal representation of the code after it has been parsed that is used usually by the interpreter or the compiler that actually be the instructions. That's a slight oversimplification but I think that's basically it. STEVE: That's pretty reasonable, yeah. NOEL: Some languages you can. Most modern Smalltalk environments let you directly edit the AST but Steve, you were saying, for some languages, it's not stable. STEVE: Yeah. Smalltalk is not changing anytime soon, so it's totally fine but for any real production implementation of a language, that's considered an internal compiler detail that gets shifted around for the compiler's needs, not for users. This is actually been a really huge problem in Rust because our macros are AST based, so there's a lot of issues. Basically, the problem is that those internal representations aren't generally stable and keeping them stable is a lot of work. That's one of the biggest reasons. I totally agree that this model programming would be awesome if it existed but people have been saying it for like 30 years, maybe even 40 years at this point and it hasn't happened yet, so I am not holding my breath that it's going to happen for real anytime soon but it would be so cool, for sure. JAMES: Yeah, that's totally fair. I'm not, I guess, saying as much that like, "I can't believe those things exist," more than like, "They kind of do exist in languages like Scratch and stuff like that." Even not editing the AST directly, you can impose more things that the language handles for you. Steve, you mentioned earlier, Rust's amazing project management system is what I'm going to call it, I guess? Cargo, right? Is that it what it's called? STEVE: Yup, totally. We usually say package manager and build tool but whatever, you're totally right -- JAMES: Yes. Package manager and build tool. For example there in Ruby, we decide where all the files go and how things get put together and what references what and things like that. When I used Ruby, I thought that was amazing to the point where I think I would have fought to defend it like, "We have to have this. We have to be able to make our own decisions," and all of that kind of stuff. In Rust, I actually can't not do that but the convention is use Cargo and that tells you where things go and it decides how things get stitched together. Am I representing that fairly? STEVE: Yes. JAMES: After having used Cargo and Elixir has a very similar tool called Mix, even in the Ruby community these days, I would say, it's more normal to let Bundler make a lot of those decisions for us and to start gems with things like Bundler new and now that that's happened, I would never want to go back. I love it that that kind of stuff gets handled for me and when I want to build my project or whatever, turn it into an executable or whatever. The tool It already knows how to do that because it knows the layout of things and there's no reason our editors couldn't adapt to be aware of those constraints and stuff. Instead of doing "file new", navigating to a directory and making sure to name my file correctly so that it matches the name of whatever module I'm creating, there's no reason I couldn't tell my editor, "I want to add a module," type a name for it and it do the correct thing. STEVE: Yeah, that would be super slick. NOEL: Even a lot of the JavaScript frameworks are settling on file layout and things like that and in ES6 modules, where you don't actually necessarily name the export from the file. The build tool just gives it a name based on the file name, if I'm describing that comprehensively but you have this potential complexity being narrowed down. I do think that we as developers tend to treat complexity that we have mastered, as like foundational to what you need to know to be a programmer and therefore, resist efforts to get rid of it even when that would be a great thing. STEVE: Definitely. JAMES: Right. STEVE: James, your story reminds me of something for me that was almost the exact opposite, which was that a way that Rust taught me about Ruby. When refinements were being proposed in Ruby, I was very publicly and loudly against the idea of refinements to the point of sitting down and talking to Matz and Headius and a bunch of other people in multiple conferences and really publicly being like, "I think this is a really bad idea." But then, that was right around the time when I sort of left Ruby or maybe I just stopped caring about it and I went off in the Rust-land and Rust has this concept called traits. There's one aspect of traits that works literally the same way refinements do. Basically, you can sort-of think in Ruby terms that a trait is kind of like how we use modules that define some code and then you mix it into other code to some degree. But in Rust, you can only have that mixing in happen if you import the trait into the scope that you're using it, which is similar to the refinements model. This refinement only applies if you put it into the scope. I found myself loving this feature that in Ruby I had fought so hard against and I don't think that I've still yet to fully un-cognitive dissonance myself about why that was the case. I don't know how much refinements are used in today's Ruby or if it's generally considered to be a success or a failure but I definitely like my experience in this other language has made me think that they're a great idea now and not a terrible idea. NOEL: I have literally never seen a refinement in the wild yet. JAMES: I haven't either. I want to kind of add on to that, though. Elixir has not quite refinements-like things but it does have things like import where you can basically bring in functions from other modules and stuff like that but one of the things that I feel like that's kind of different between an Elixir and Ruby and this area is Elixir has the philosophy that things that can be should be explicit. It's like, Refinements I believe are that way in Ruby and you're guaranteed to be able to scroll up to see where the refinement came from, but that's always true in Elixir. In Elixir, if you call something in the middle of a file and it's not defined in that file, you are guaranteed to be able to scroll up and find an import or an alias or something that will tell where that thing came from. To me, that makes all the difference in the world. I have no problem with magic when I can figure out where it comes from. I think one of the problems Ruby gets into sometimes is that there's all this magic and when you're like, "Where does that come from?" that's a really hard question to answer sometimes. NOEL: It's often hard, especially for people new to Ruby and Rails to figure out where things are defined in that. James, tell me what brought you to Elixir and tell me a little bit more generally about what Elixir is and what it tries to do. JAMES: I actually started looking at Elixir several years ago. A buddy of mine that I used to work with was pretty into it. He was like, "You should check this out. It's pretty amazing," and at the time, I looked at it and I did think it was neat but I was really comfortable, I guess in Ruby-land and I don't feel like I really gave it a very fair shake, sorry Nathan. But I kind of blew it off and then I kept running into these problems over and over in my job, where I am building a web app but what we're doing is something like... in education, we're giving students a quiz and so we go back and forth with them over several questions for a period of a time while they're in the computer lab, maybe 30 minutes to an hour. Or at a market research company, we're getting some of our community members to take a survey to give us some information on something. We’re going back and forth with them over this period of time, where we're giving them a survey and then we're done with them for a while. What they kept finding is this is terrible for the traditional model of the web app. Because a web app is stateless, the first thing we do in every single request is a whole bunch of queries to reestablish the state of the work and where we are. Then, you have this back and forth that you're having with their quiz, survey or whenever. It has context and it has like where you are in the process. You don't want to ask them a Question 1, they answer the Question 1 and then you ask them Question 1 again. You want to ask them Question 2, which requires you to remember where you were. In one of my projects this was a particular pain point because we were getting pretty popular and having a lot of incoming traffic and then, when you're in the middle of that traffic, during all those queries to reestablish the state of the world is expensive. There's lots of solutions around these in the web world, introducing tools like reddis and stuff like this, to cache the key bit of what you're doing right now, so that you can get those faster but it's still the same fundamental problem and you're trying to do Step 1, then Step 2, then Step 3. What happens is when they come in, wanting Step 3, you spend a bunch of energy reminding yourself that you're on Step 3. Does anybody else felt this pain working with web apps? NOEL: Yup. STEVE: Totally. JAMES: Cool. This is like a pain of web apps. It's not all web apps. Obviously, a blog does not have this problem. There's lots of web apps that don't have this problem but some do. Elixir is designed in such a way and this is not unique to web apps but it's designed in such a way that it just kind of naturally solves this problem and it's actually like not a thing and the reason for that is that Elixir, like Erlang, runs on the BEAM virtual machine. Inside the BEAM, you have this amazing concurrency model called the actor model generally and in Elixir and Erlang, you can spin up processes. A process is kind of a self-contained bubble of logic and the state that it's working on. That may sound a little bit like an object. It kind of is and it's kind of not. It is like an object in that there's this behavior and the state that is working but also, by definition, all of these things are concurrent, so whether you want it or not, it's concurrent and you have to deal with it. But the advantage to something like that is if you are solving one of these "remember the context of what you're doing right now" problems, it's basically almost free. For example, when somebody starts taking your quiz, I can spin up a process. On that particular process, for that student taking that quiz and in there, I can program almost linearly: do Step 1, and then Step 2, then do Step 3 because it's only that student that's being tracked by this given process. Then we have ways to keep the context when we're talking to that process like web sockets are huge thing in Elixir because it allows us to keep that conversation going and then you have things like wouldn't you be speeding up the process for every single student taking a quiz at the same time and when that leave us just tons of processes and the answer is yes and luckily the BEAM can launch literally hundreds of thousands of processes before you even have to start turning any dials. If you do turn dials, then obviously, you can get that number way higher. What led me to Elixir was the desire to address this problem that I kept running into over and over again in a different way and finding a language because a buddy of mine had me look at it one point. It made me realize that it was totally capable of handling this problem in a completely different way and that lead me to using it for a very practical reasons. NOEL: The virtual machine that is built on is designed for massively parallel telecommunications. It predates the web, doesn't it? JAMES: It's been running at a majority of the telecom industry for over 30 years. NOEL: And for a long time, the way to communicate with that virtual machine was Erlang, which is a language that is not known for having super friendly syntax. I don't know it myself. But then Elixir was designed -- you're going to correct me because I'm going to be wrong -- specifically to be more friendly to dynamic language programmer's syntax for interacting with this massively parallel virtual machine. JAMES: Yeah. I think you got pretty much all of that correct. Erlang was pretty much the only game in town for running your code on the BEAM, which is this amazing architecture I've been describing and Erlang is somewhat unpopular for its unusual syntax. That said, I will say that I'm pretty sure it's mostly because of what we're familiar with. There seem to be multiple paths in language syntax and most of our modern languages have a C-like syntax, which actually comes from Ada, maybe. I may have that wrong. STEVE: Ada is a Pascal variant. NOEL: No. C has some predecessors but C itself was the big influence on almost everything else. JAMES: Okay, cool. Anyways, they have a similar C-like syntax but Erlang went to a different way. I'm pretty sure it adapts its syntax from Prolog, I believe it's the inspiration. STEVE: You're totally right. JAMES: And it looks different to us. So, Elixir's syntax is directly inspired from Ruby. If you are a Rubyist, then you probably feel very at home in Elixir syntax. It's not like that. Ironically though, if you get deep enough into learning Elixir, you almost have to learn some Erlang along the way. You will be reading some Erlang and before when I tried to learn Erlang on my own, I did have that feeling of kind of off-putting syntax but now that I understand the BEAM and the environment, it's running in, I'm learning it through Elixir, it's funny but the syntax doesn't seem to bother me anymore. I have a pretty good idea that it's probably just more of what we're familiar with, than the syntax being particularly terrible. NOEL: To pick up on a little bit of the theme here, what did Elixir teach you about programming and what does it do to help the developer experience? JAMES: Elixir is a functional programming language. That's not to say that it's better than an object-oriented programming languages but like what Steve said, it's almost fundamentally different from them. You go to Rust because you can learn a lot about typing and how types can help you create better programs. Similarly, functional programming makes you think about things in totally different ways. For example, functional programming often includes things like immutable data structures or pattern matching and things like that and when you have those things, you solve problems in slightly different ways and you do things in different ways and you gain advantages for that, in my opinion, the ways that it pushes you to think about those things. Even non-strict functional languages are starting to recognize this and adapt several things. We're seeing JavaScript get some, if not full -on pattern matching at least restructuring and stuff -- STEVE: The part of the reason why that's happening is because Rust has pattern matching, which is descendants from ML family languages, which shared this history. But the reason that JavaScript proposal is being made is because the person who made it had started learning Rust and liked it so much, that it is moving in to JavaScript. I'm not saying you're wrong. I'm saying it's like many different influences come through in different ways. Which is really neat. NOEL: Now, I'm going to ask you to define pattern matching. STEVE: Pattern matching is this construct in many programming languages that allows you to... think of it like an if statements but much, much more powerful. Instead of like 'if-else, if-else, if-else,' you say like, "I would like to match against this thing as a pattern," and then you provide a number of different patterns and what you want to happen if they match. By pattern, usually what I mean is it's like some sort of syntax that looks like the thing you're trying to match against. Maybe if you had an object, it would have like the members of that object or if it was a number, it would be a number or whatever but it kind of gives you this ability to do multiple if-else’s in a much, much cleaner and nice way. JAMES: Depending on how heavily your language supports it, it can really be a major impact on what you're doing. For example in Elixir, when you are defining your function's parameters, your formal parameters, those are pattern matches. You do the pattern match right there when you define what that parameter is and that can be things like, it has to be a map -- which is equivalent to a hash in Ruby -- with these keys or whatever. And that can actually define multiple function heads for the same function using different pattern matches. When Elixir ends up calling the function, it runs through those pattern matches to find the one that matches, so it only ends up executing that version of the function. So, One, This keeps your function shorter. Two, It makes it so that if none of the patterns matche, you'll get an immediate error like, "You're calling this thing that doesn't make sense. It doesn't take this kind of data and work on it," and it makes error handling and stuff like that much nicer. STEVE: Yehuda and I came into the Rust world. I came in first and then wouldn't stop talking about it and so, Yehuda tried it out. He liked it too. One of the things that I like to say, Rust has people that come from many different backgrounds but the people who come from a Ruby or Python or JavaScript background, the influence they had on Rust development was not accepting that your life needs to suck. For example, when I came to Rust, you would be writing make files to compile Rust code. I looked at that and I was like, "This is not what I want to be doing," and through the work of many people, we convinced Mozilla to invest in paying Yehuda to build Cargo and that was like, "We're used to this tool. We want this tool in this language too," and so, that's played this way out a number of different things where the lower level programmers are kind of used to things being complicated and hard and as Rubyists were like, "No, things should be easy and fun. Let's figure out a way to make it easy and fun while still respecting the low level nature of the problem at hand," and that's definitely had a huge impact on this development. JAMES: I want to kind of go along similar lines of that and say that, I was a little bit worried where I first started talking about this podcast that instead of being called like, "Ruby after Ruby," it was going to be called something like, "Ruby is dead to me," or whatever. I feel exactly the opposite of that. I still use Ruby every day in my job. We have pretty much four main applications and the largest one of them is Ruby. The other three are Elixir and we do write a lot of Elixir but I write a lot of Ruby too and I still use it and I still love it and like Steve, I have a tattoo, so forever it's a part of me. Then, there are things that Ruby does well that Elixir sucks at. For example, as a scripting language. Multiple times now, I've done some scripting in Elixir and you can totally do it and I'm not saying it's terrible but there are things that Ruby just does so much better as a scripting language. From its handling of standard in and standard out and building standard UNIX filters and stuff like that that Elixir wasn't designed for because it's designed to run these sets of processes and supervision trees, which allowed to do things like run forever and are amazing but it just kind of runs counter to that, the scripting goal of slap these three things together and get something back and Ruby is better at that. The one thing, I think I've really learned from seeing the different communities is how much I appreciate each community for what is unique to each and what it teaches me and how I can bring those things together as I work in other communities, like in bringing the good parts to Elixir to Ruby or the good parts of Ruby to Elixir. I think in general, I want to be kinder to everyone's language community because I'm sure they have something that I don't. STEVE: Definitely. I want this to super, super reemphasize that sentiment. The first part of that, I hyper-empathize with that so much. NOEL: Well, that seemed like a good place to wrap up. Where can people reach you online, if they want to talk to you about these other language communities or anything else? Steve? STEVE: I'm happy to get emails from people but it can take a couple of months to reply sometimes because I'm terrible at emails. That's fine if you have something that's not hyper-immediate. I am always on Twitter, so if you follow me on Twitter, I'm sorry/thank you. You can tweet at me without following me and I always like to talk on there too. Those are generally the easiest ways to get a hold me. NOEL: @steveklabnik on Twitter, right? STEVE: Yes. NOEL: And James? JAMES: I'm also on Twitter. It's at @JEG2, for James Edward Gray II. I am moderately active there, I do try to respond to those things. If you follow me right now, you'll probably see me tweeting me a lot about Gig City Elixir, which is a conference that I'm helping to run in October about Elixir. If you want to learn more about Elixir, you're getting into it and you'll see what makes it great. It might be fun to come at to that conference. It's in Chattanooga, Tennessee. NOEL: Great. Thank you both. This has been a lot of fun and that's it. Tech Done Right is a production of Table XI and is hosted by me, Noel Rappin. I'm at @NoelRap on Twitter and Table XI is at @TableXI. The podcast is edited by Mandy Moore. You can reach her on Twitter at @TheRubyRep. Tech Done Right can be found at TechDoneRight.io or downloaded wherever you get your podcasts. You can send us feedback or ideas on Twitter at @Tech_Done_Right. You can also contribute to the conversation on our website. Table XI is a UX design and software development company in Chicago, with a 15-year history of building websites, mobile applications and custom digital experiences for everyone from startups to story brands. Find us at TableXI.com where you can learn more about working with us or working for us. We'll be back in a couple of weeks with the next episode of Tech Done Right.