42. Max Jacobson Guest Stars! There are no rules

On today's show we welcome Max Jacobson. We’ll be discussing the differences between Ruby and other current languages and get Max’s perspective on which language is better for certain applications. In the ever changing landscape of coding and building, everyone seems to have their own preferences, favorites and special skillsets, this conversation aims to bridge some of these gaps. Max takes us through some personal experiences and also gives us an overview of the talk he recently gave at RubyConf 2017. Max’s belief in finding what works for yourself while keeping an open mind to other solutions is one we fully support and a good lesson for any coder, no matter how experienced. After the discussion we also get into some helpful teach and learns from the all of us so tune and in and get the low down!

Key Points From This Episode:

  • Max’s experiences at RubyConf 2017 and a little about his talk.
  • Rust versus Ruby and how they are quite similar.
  • The positives and negatives of restraints.
  • The freedoms of Ruby.
  • Transitioning between languages.
  • Older languages and the preparation they require.
  • Which language should beginners learn first?
  • The drawbacks of problem solving Ruby
  • And much more!

Transcript for Episode 42. Max Jacobson Guest Stars! There are no rules

[0:00:01.6] MN: Hello and welcome to The Rabbit Hole, the definitive developers podcast in fantabulous Chelsea, Manhattan. I’m your host, Michael Nunez. My cohost today —

[0:00:10.4] DA: Dave Anderson.

[0:00:12.9] MN: My producer —

[0:00:12.7] WJ: William Jeffries.

[0:00:14.1] MN: Today, we have a special guest, Max Jacobson. How are you?

[0:00:18.8] MJ: Hi, I am great. Thank you for having me.

[0:00:20.9] MN: Awesome. Max recently gave at RubyConf 2017. That must've been exhilarating and awesome. How was that?

[0:00:30.0] MJ: Yeah, it was a thrill of a lifetime. I don't mean to sound sarcastic. I had a really great time. It’s my first conference talk, and it was stressful, but fun. Yeah, it went pretty well.

[0:00:41.5] MN: Awesome. Could you give us a little bit of what the talk was about?

[0:00:46.6] MJ: Sure. Yeah. So I was in the comparative Ruby track. So they have multi-track conference where there were four different talks going on at any given time. The one I submitted to you was called comparative Ruby, and it was kind of comparing Ruby to another programming language that I've been learning over the last like two years, which is Rust, which is a pretty different language.

When I was thinking about learning another language, I had a friend who advised, “Okay. You’ve been working with Ruby for a couple years. Maybe learn something very different.” I was saying, “Maybe I would learn Python.” He’s like, “Don’t learn Python. That's really similar to Ruby. It's great. There's nothing wrong with it, but —”

[0:01:25.5] DA: Yeah. It’s very similar. I recently switched from Python to Ruby and it just took like a weekend. You’d be pretty like done right away.

[0:01:35.0] MJ: Which is great. Like if I needed to jump on a project and want to be able to speak quickly. I’m sure there are actually a lot of differences that I'm completely unfamiliar with. But in terms of new concepts, like programming language design concepts or fundamental things that where they just behave differently, it encouraged me to pick something very different, and then I started learning Rest because one of my teachers was talking about it a lot, about how great it is and I figured, okay. This is a statically compiled language and has a lot of different concepts you need to learn, but sort of superficially, it doesn't look that different. It’s not super scary looking.

[0:02:11.2] DA: It’s not like C++ or C.

[0:02:13.8] MJ: Yeah. The cool thing about it I’ve learned now is that it kind of is like them in terms of what it's like useful for, but it kind of looks like Ruby and JavaScript kind of mashed together and then a bunch of typeset on top.

Anyway, the talk is about my experience learning Rest after learning Ruby and working with Ruby for a few years and the way that it sort of changed the way that I think about Ruby. So the title is There Are No Rules in Ruby.

[0:02:38.4] DA: Sounds about right.

[0:02:40.4] WJ: It’s very true. You can do pretty much anything, and it’s kind of scary.

[0:02:43.9] MJ: The wild, wild west of programming.

[0:02:45.9] DA: I once found a method in a library that was using a Ruby that was an emoji. I needed to clear a queue, and it was a bomb.

[0:03:01.4] MN: No! For real?

[0:02:59.7] DA: It is very true that there are no rules.

[0:03:01.6] WJ: That’s q.bomb!

[0:03:03.4] DA: Yeah, exactly.

[0:03:04.5] MN: No way!

[0:03:05.7] MJ: Yeah. There are a lot of things that you can do in Ruby. You can have any valid Unicode identifier and that includes things like emoji. I just kept finding that the more I used Ruby after learning Rust, the more things felt kind of wild west, I think I heard someone say.

[0:03:23.7] MN: Yes.

[0:03:24.1] DA: Yeah. It’s kind of scary. So kind of went the other way. Like my first language that I spent a lot of time with was Java, which is statically type much like Rust. Very strict, where you have to define your interfaces and all of that, and then I moved to learn Python and it sounded terrifying. There was just so much freedom. Anything was possible and it took me a while to get used that.

[0:03:48.3] MJ: Yeah. So the thing I started thinking about is that I think that there are a lot of kind of career trajectories and learning trajectories depending on what order you learn things in. Where if you start with a language like Ruby and then you go and learn a language like Java or Rust, you might react differently depending on who you are, but you might be kind of open to the idea of that. You could write very flexible code and you can make that work because you’ve experienced it. If you’re going the other way, you might be like, “Oh my God! My types. I need my types. How am I going to ever write reliable production code?”

I sort of had that experience of all, “Oh my God! All the things about Ruby that are kind of challenging,” a lot of them anyway don't necessarily have to be that way or a lot of things that I sort of taking for granted. It was very much because of my own ignorance, where I just hadn't really used statically type language before and it was a really interesting experience to realize, “Oh my gosh! That can help.”

[0:04:43.3] DA: Yeah. A lot of people use dynamic languages, kind of rail against, having types. It's funny seeing the pendulum swing the other way a bit. I’ve recently worked with Flow in JavaScript, which is a typing extension and of course there’s typescript and numerous other ways. Also with Python, there's Mypi which lets you put types in your Python, which seemed crazy at first, but why not?

[0:05:10.7] MJ: Right. It's like putting on the shackles and being happy, because you feel like it might be helping you write more safe or resilient code.

[0:05:21.8] WJ: I love my shackles.

[0:05:24.2] MJ: Yeah, and it's a weird transition to make. It's very much like changing your mental perspective from where you're looking at the world. Yeah.

[0:05:32.9] WJ: Also, you don't have to allow people to monkey patch the string class, which is like a really nasty thing that people could do in Ruby and that I've gotten burned with.

[0:05:41.2] MJ: Yeah. When you add gem as a dependency to your  project, it's running whatever code it's got, and that could be monkey patching string. It could be removing all the methods from string. In theory that could happen. You could require a gem and now strings have no methods.

[0:05:57.5] DA: That's pretty [inaudible].

[0:05:59.3] MJ: Exactly, yeah. A lot of these stuff I sort of — After like thinking about a lot and talk to a lot of people about this, I’ve sort of come to realize a lot of the things that I am sort of afraid of are never going to happen. Not that I like really realistically thought that would happen, but on some level it bothers me that it can.

[0:06:18.0] DA: Yeah. It is a little bit disorienting. I remember like when I first started learning Rails and you have all these monkey pass methods on all of the objects, like with active support, and it's like, “What do you mean like my regular string in my Ruby REPL doesn't have like 2jOSn of my hash doesn’t have 2jOSn or whatever,” convenience methods that are just magically there when you’re using active support.

[0:06:45.3] MJ: Yeah. That’s sort of I think gets at another topic that I was really interested in thinking about and talking about is this idea for beginners who are learning their first language. I feel like that’s the kind of thing that can trip people up when they build their mental model, “Okay. When I have a string, I can call 2jOSn.” If that’s something they’ve done, they start thinking that's how Ruby works, and then they have bugs later on while they’re developing when that method is not defined.

The thing I started wondering is all these things that make Ruby really flexible and really productive for like advanced programmers, what if those make Ruby harder to learn? That was a fear I started being a little obsessed with. I think that we talk about Ruby. I'm curious if you agree with this sentiment as being a really great language for beginners.

[0:07:30.1] MN: I believe so, similar to Dave. I learned Java first and that was like my first professional career language, and then I went to Ruby and was paralyzed at how easy things just magically happened a lot of the time, like how unrestrictive you are like how there are no rules. After learning Ruby I realized, “Oh! This is a great language.” Had I started learning this first, it would have been a lot easier than the overhead you have with types and Java.

[0:07:58.3] DA: Yeah.

[0:07:59.0] WJ: Yeah. I also started with Java and I think now — This might be a symptom of us all having not started with Ruby. Maybe we’re not the right people to ask. But it does seem to me like there's so much boilerplate set up to get anything to happen in some of these older languages like Java that the freedom that you get by being able to have a main object and not have to set up your class and your public static void main and all of the ceremony makes it so that beginners can write, print, hello world and be done, whereas in Java that would be like six lines of code.

[0:08:36.3] DA: Yeah. I've heard an interesting philosophy recently about like teaching beginners on Ruby and how they need to earn every little bit of convenience as a language gives them. Like before you can use a map function or for each function you need to understand what the four loop is and then once you have that, then like — Yeah, you can build off of that and say, “Okay. Now you can unlock this and use these things and keep on building up,” and eventually use all of the fancy aliases and whatever else that Ruby offers.

[0:09:10.2] MJ: Right. I think that's a really interesting point and I think the way that I think about it when I’m in a teaching context is that you want to teach someone a concept and you want to teach them something kind of high-level and interesting that they're going to be compelled by and be able to use to do something. But you can't really start there, because it's too much all at once. You have to break it down into the smallest units that you can and then reassemble this little tower of ideas until you reach the thing you really wanted to get to. If you try to start there, it's too much to really fit into your head all at once.

So the thing I started to worry about is what if the whole language with Ruby is too much in the sense that when you start hitting problems you don't necessarily have the tools to understand what's happening, because anything could be happening. There are so many things in such a big language that have so many built-in keywords and large standard library and there's so much going on that it can be pretty easy to fall into a trap.

[0:10:10.2] DA: Yeah, especially with like alias methods that are doing the same thing and you’ve never seen them before, or like with Rails, like your context is all of the things that exist lot of the times, like helpers and whatever else. It can be hard to reason about what are the scope of possible things that could be happening at whatever given time.

[0:10:31.7] MJ: Yeah. So I started worrying about this and convincing myself that therefore a smaller language is necessarily better for beginners. Something like Rust, to come back to that a little bit, is kind of like Java a little. It has a lot of the same trappings where you’re defining types and you have to have a main function, but they make really big efforts to do away with anything that's not really necessary. So it's sort of easier to get up and running. It's certainly not as easy as with Ruby, but they have made tons and tons of efforts on what they call, I think, the ergonomics initiative to do away with all of the barriers and make it a really powerful language that is also accessible.

I started working my way backwards to that opinion, but in reality, Ruby is kind of great for beginners. I have this theory that actually I don't agree with. I don’t know if that ever happened to you.

[0:11:24.0] WJ: Yeah, definitely. Usually I flip-flop like 8 times. You have your opinion, like this is wrong.

[0:11:31.5] MN: Max, you have mentioned before you worked in Rust for some time and working in a statically typed language like Rust or Java is the conversation we had before. That feels like you're working with shackles and how everything is statically typed and Ruby is dynamically typed and everything is in the wild, wild west. What were some of the differences or something that you would like to see that was done in Rust when you went back to Ruby land you wish you had, or like what are some of the key differences that you see between one language or another and the benefits of using the shackles, that is Rust?

[0:12:06.3] MJ: Yeah, the shackles that we sometimes like and maybe sometimes don't. One thing about them that I do like that I talked a little bit about in the talk is the different model of error handling that Rust has compared to Ruby. When Ruby — When a problem happens, an exception gets raised, so it’s an exception model, where an error gets raised and then the person that called that method can decide if they're going to rescue it, and if they don't rescue it then the program will crash. That's the exception model and that's in Ruby.

Rust, it has error model where instead of raising an exception, a function that might have a problem go wrong. For example, if you have function that reads file and returns the content to the file, that could go wrong if the file doesn't exist, if the file is like encoded in a funny way that we can't read or we don’t have permission to read it. There is a number of different ways where that could go wrong. Looking at that function signature we will be able to see exactly what those are.

So with Ruby you don't necessarily know looking at — Like you see, “Okay. There's method read file,” but you don't necessarily know what it returns or if it raises the errors, or if it does, what are they? With Rust, the convention is that if your function could either succeed or fail, it will return a results type, which is either success, which they call ‘okay’, or failure, which they call ‘err’.

In the type signature, because it's typed language, you can see exactly what type of error it could be, and so you can plan really effectively. You kind of can think about every problem that could happen while you’re writing the code and decide exactly how you want to handle that. So the result is that your program is very unlikely to crash in an unexpected way because you were sort of forced to think about it all up front, because in order to actually read the okay value you need to check, is it okay or not.

That's sort of the beautiful dream ideal of this error model, and I believe that and was excited about that. The more I actually wrote Rust code, I sort of learned that you also don't have to do it the right way. You can also use this function called unwrap, which is just like, “Ah! It probably worked. Just unwrap it. Give me the okay value. If it's not okay, feel free to crash,” which is sort of discouraged, but it is allowed. Part of my journey here with Ruby and Rust is I started really drinking the Kool-Aid and really wanting to believe that Rust had all the answers and that it would force me to write perfect code, no problems and always does the right thing.

It turns out that's not technically a hundred percent right, but it does provide tools to help you go in that direction, and it has conventions just like Ruby has conventions, that your function shouldn't panic. They call it panicking if you unwrap an error, that it shouldn't panic it should return the error. I really like that and I kind of wish Ruby had that.

[0:15:15.4] MN: Ok. Right now you’re currently writing production code in Ruby. Would you be more interested in writing production code in Rust store or Ruby? What are your thoughts on one versus the other? Which one do you think is better to work with overall?

[0:15:30.4] MJ: Okay. Great questions.

[0:15:32.6] DA: It’s a trap.

[0:15:33.6] MN: Yes. It is, by the way.

[0:15:35.1] MJ: I have way more experience using Ruby and I'm way more good at Ruby. If I actually had to jump in to be productive, I would almost definitely go with Ruby. The other thing that I think is sort of interesting about this is that even if you come to the conclusion that Rust is better, which I'm not necessarily there yet or anything. It doesn't mean necessarily that you should use it for everything, that there’s always trade-offs and everything. One of the big trade-offs of the Rust is that the like library ecosystem is way less mature. You would probably end up writing a lot more code where you just include a gem in Ruby and they would take care of like sending emails. Like maybe that exist in Rust. I don’t know.

[0:16:15.1] MN: Right. There's way more community backing in Ruby, because it's been out for many years now, versus Rust that has a smaller community and doesn't have as much packages or gems or — What are Rust crates.

[0:16:29.5] MJ: Crates.

[0:16:29.5] MN: Rust and crate — Yeah. There’s not a lot of crates enough like Ruby has gems. Gems sounds — Yeah. That makes sense. I imagine as the community grows, there will be more crates.

[0:16:43.2] MJ: For sure, and if you are the kind of person that likes doing open-source work, it's kind of a cool opportunity because you can fill in those gaps and you can be the person that writes the web framework for Rust. There're a number of micro-web frameworks for Rust and none of them have like "won” yet. So like there's kind of a burning up-and-coming war that I think will come. There's this one called Rocket that seems like it might be going off. I'm not sure.

[0:17:06.3] DA: That’s the most aggressive sounding name.

[0:17:08.3] MJ: Rocket. Yeah. I don't know. In Ruby we talk a lot about programmer happiness, and I think it's interesting to think about why exactly Ruby provides programmer happiness. That’s one of the goals of the language, and I think that it does. It has a lot of, million amazing things about it and it feels really great to write Ruby. It has a really good workflow and it sort of feels like you're expressing your ideas in real time.

The part where I sort of feel like it may be provides a less programmer happiness in this facet than maybe Rust is, is in things like maintaining a project overtime. This is an untested theory, but I don't know. Do you often have bugs in production that feel like, “Oh! I should've thought that that might happen. I should've checked that [inaudible 0:17:50.8] I should have.”

[0:17:51.6] DA: Nulls.

[0:17:52.7] MJ: Yeah.

[0:17:53.9] MN: Nulls.

[0:17:55.8] DA: Oh, man! Yeah. Yeah, that’s happened for sure, and it's interesting because some of the folks that are the biggest proponents for static types in dynamic language, like Python, Dropbox, like their entire code base is Python and they're the ones who were pretty largely bankrolling the static types in Python, because they have a huge code base and it became very hard to reason about.

[0:18:20.5] MJ: Yeah. I think that does make me programmer unhappy. I am not prepared to come down on either side.

[0:18:27.6] DA: Yeah. I guess also like something that makes a programmers happy is having a smarter ID and having exactly type language, lets your IDE be a lot smarter and help you be a better programmer. I’m sure like you’re talking about the exception handling or error handling, how it’s built into the definition of the function, like I'm sure your IDE could easily be like, “Hey, that’s a dangerous function. You need to watch out for it,” and this is how things could go wrong.

[0:18:55.4] WJ: Yeah, that jump to definition feature in like JetBrains products for statically type languages. Oh man! I miss that every time I use a dynamic language. You can get kind of close with C tags, but it's not the same.

[0:19:09.1] MN: JavaScript is like really difficult at times. It’s like, “Wait. Which function that has the same name?” It’s just like I get sad. I know that I believe WebStorm could kind of figure it out sometimes and sometimes-

[0:19:22.0] DA: Yeah, I went to a talk that the creator of Turn, which is like code analysis tool for JavaScript. He’s talking about like, “Oh my gosh! Source trees and doing all these amazing stuff, and then I can go to the definition or know what this thing is.” I'm like, “Wait! I'm coming from a Java background, so I don't understand why this is important. All of the JavaScript [inaudible 0:19:40.7] are like losing their minds. It is really cool. It's very helpful. It makes programmer happy.

[0:19:46.9] MJ: For sure. Yeah. That's another thing where because of my trajectory coming from Ruby to Rust, have no experience with that, and the IDE story is kind of young as well. There's this thing called the Rust language server which is a server that runs that can provide information about your source code to whoever wants it. Now, editors are integrating with the Rust language server. The best one so far is Visual Studio code, which shows you all of the information about your code, and as you're typing it will do things like say, “Hey, you need to handle all of these different kinds of errors that may come back from this function.” If you miss one, it will tell you. It’s pretty good.

[0:20:27.0] MN: Hate me, but I identify use Visual Studio code, and I think it's amazing. I love it. I don’t know why. I just think it’s cool.

[0:20:33.5] DA: I don't hate you.

[0:20:34.5] MN: Okay. [inaudible 0:20:36.5]. Microsoft gets a bad rep. VS code is dope. I definitely love VS Code.

[0:20:44.6] DA: I’m glad we cleared the air.

[0:20:45.3] MN: Yeah, exactly. [inaudible 0:20:46.6]. Cool! Do we have any teach and learns today?

[0:20:52.0] DA: Yeah, I think we do. I’ve learned and taught some things recently.

[0:20:55.8] MN: Awesome!

[0:20:56.6] MJ: I'm new to teach and learns, but the same.

[0:20:59.4] MN: Yeah. Recently I've been working more with Jest and Snapshot tests and wanted to find a way to like integrate Enzyme for doing shallow rendering of React components with Jest and started using enzyme to JSON, and it's pretty nice. Jest has this nice little hook to serialize all of the enzyme things and it just happens seamlessly under the covers, and it’s great. I love it.

We spoke about Jest a couple of times on the podcasts and I still haven't given it a chance since the first time I've ever used Jest when it first came out, and that was like insane usage. I hear a lot of good things about it now and I should definitely give it a try.

[0:21:43.5] DA: Yeah, peer pressure.

[0:21:45.4] MN: Is that just a visual testing thing? I've never used Jest. I’ve never used React.

[0:21:52.4] DA: For those who are not familiar with Jest. Basically, it is a testing framework that Facebook came out with. For the most part, it’s just a test runner and gives you described blocks, but you can also have snapshots where it will just capture a value similar to VCR in Ruby for like API requests and it'll just compare that to it. So it’s like kind of the opposite of TDD, because you're developing and then you’re looking at the output of the snapshot and be like, “I like that. Let's keep that one.” But it can be nice, because like you capture really nitty-gritty things that I would not care to write tests for 10,000 little details or how my visual components are looking.

[0:22:39.6] MJ: Yes. It’s like a really interesting combination of automated and manual testing.

[0:22:42.7] DA: Yeah, exactly. You’re saying that you had something as well.

[0:22:45.5] MJ: Oh, yeah. I wanted to share a tool I started using recently for Ruby debugging. I'm a fan of writing short little Ruby scripts to illustrate problems and try to understand ideas, and what I usually do is go into IRB and write a line, hit up arrow, change a line, do that over and over and it's kind of great, but I found this cool tool called Seeing is Believing, which is the tool that [inaudible 0:23:12.9] uses on the Ruby Tapas screencast, and so it has a Vim plugged and an Emax plugin, and the ideas is that you write your Ruby script and then without even leaving your editor, you just like hit enter and it runs the program, captures the output and then inline the output back into the program as a comment. So you can keep tweaking things. Keep hitting enter and it will replace the output with the new output. I just find it really pleasant for debugging and kind of playing with Ruby.

[0:23:39.6] MN: Awesome. Seeing is Believing was the name of the —

[0:23:42.2] MJ: Yes. There's a gem called Seeing is Believing, and then I use the vim plug-in called like vim-seeing-is-believing.

[0:23:48.4] DA: Awesome. We have to check that out.

[0:23:51.5] MN: Great. Max, where can people reach you in the internets, if you will?

[0:23:56.3] MJ: Sure. Yeah. I have a blog at hardscrabble.net, and I'm on Twitter @MaxJacobson.

[0:24:02.8] MN: Awesome. People can find your talk during those platforms I imagine?

[0:24:09.5] MJ: Yeah. It will be on my website.

[0:24:11.5] MN: Awesome. Cool. It’s great having you, Max Jacobson. Thank you for coming on. I greatly, greatly appreciate it.

[0:24:17.5] MJ: This is super fun.

[0:24:18.7] MN: Awesome. I'm glad you had a good time, because that would be super awkward if you didn't have a good time.

I like to think my cohost, Dave Anderson. Thank you for coming on out.

[0:24:28.9] DA: Thanks, man.

[0:24:30.4] MN: And our producer, William Jeffries. Thank you for joining in on the conversation.

[0:24:33.8] WJ: Great to be here.

[0:24:34.4] MN: Feel free to hit us up at twitter.com/radiofreerabbit. I’m Michael Nunez, and this is The Rabbit Hole. We’ll see you next time.

Links and Resources:

The Rabbit Hole on Twitter

Flow

Rust

Python

Visual Studio

Jest

Seeing is Believing

Max Jacobson Blog

Max Jacobson on Twitter

Max Jacobson at RubyConf