The Changelog: Software Development, Open Source - Types will win in the end (Interview)

Episode Date: July 13, 2023

This week we're talking about type checking with Jake Zimmerman. Jake is one of the leads at Stripe working on Sorbet — an open source project that does Type checking in Ruby and runs over Stripe's ...entire Ruby codebase. As of May of 2022 Stripe's codebase was over 15 million lines of code spread across 150,000 files. If you think you have a bigger Ruby codebase, Jake is down to go byte-for-byte to see who wins. Jake shares tons of wisdom and more importantly he shares why he thinks types will win in the end.

Transcript
Discussion (0)
Starting point is 00:00:00 What's up friends? Welcome back this week on The Change Lab. We're talking to Jake Zimmerman. Jake is one of the leads at Stripe working on Sorbet. Sorbet is an open source project that does type checking in Ruby and runs over Stripe's entire Ruby code base. As of last May, that code base was over 15 million lines of code spread across 150,000 files. If you think you have a bigger Ruby code base, Jake is down to go bite for bite to see who wins. Stick around because Jake shares tons of wisdom and he also shares why he thinks types will win in the end.
Starting point is 00:00:34 A massive thank you to our friends and our partners at Fastly and Fly. This podcast got you fast because Fastly is super fast all over the world. Learn more at Fastly.com. And our friends at Fly help us put our app in our database close to our users with no ops. Check them out at Fly.io. So I'm here with Ian Withrow, VP of Product Management at Sentry. So Ian, you've got a developer-first application monitoring platform. It shows you what's slowed down to the line of code.
Starting point is 00:01:16 That's very developer-friendly and is making performance monitoring actionable. What are you all doing that's new? What's novel there? Traditionally in errors, what's the strength of Sentry is we've taken not a stream of errors and said, hey, go look at this, like all these error codes are flowing into SES. We actually look at them, we try and fingerprint them and say, hey, we've actually grouped all these things. And then we give you everything you need within Sentry to go and solve that error and close that out. And that's, I think, driven tons of value for our users. And traditionally, if you
Starting point is 00:01:52 look at performance, it's not that thing. It's looking at certain golden signals, setting up lots of alerts, maintaining those alerts, grooming those alerts, and then detecting them. And then maybe you have a war room and you try and look at traces, or maybe you realize, oh, it's this engineering team that owns it. Maybe they'll look at logs, whatever they have available. Performance is very rotated on detection and then isolating to where the problem may exist.
Starting point is 00:02:18 And root causing is often an exercise left to the user. Good performance products provide a lot of context and details that an experienced engineer or DevOps professional can kind of parse and make sense of and try and get to a hypothesis of what went wrong. But it's not like that century error experience where it's like, here's the stack trace, here's all the tags. Oh, we see it's like this particular segment of code,
Starting point is 00:02:46 and Ian did the commit that changed that code, and do you want to fire your issue and assign it to Ian? It's not that crisp, kind of tight workflow that we have here. This is breadcrumbs. Right. And we said, hey, maybe there's no reason why we couldn't do this for performance. Let's try. Okay.
Starting point is 00:03:04 So you took a swing. You tried. Describe to me how that trial works. If I go to my dashboard now and I enable APM on my application, what are the steps? Largely because we kind of encourage you to go and set up transaction information when you set up Sentry. You probably, as a user, probably don't need to do much.
Starting point is 00:03:22 But if you skip that step, you do need to configure to send that data in your SDK. And what happens is we start now looking at that information. And then when we see a, what we call a performance issue, we fingerprint that, and we put that into your issues feed, which is already where you're looking for error issues. Right. It's not a separate inbox. This is the same inbox. The same inbox. Yeah. Now we obviously give logical filters. And if you just want to look at those, we do that. And for newer users, sometimes we detect, hey, you've probably never seen this before. We can kind of, we do things because we know we build for mass market that bring your attention to it, but it's the same workflow you have for errors today. So you don't have to learn something new
Starting point is 00:04:03 to take advantage of these things. So you asked the experience. So last fall, we did the experiment, the first one, which we called M plus one. And we didn't know how it was go, honestly. But people liked it. Like we kind of know people like it when they start tweeting and saying nice things about it.
Starting point is 00:04:20 And so, yeah, it got traction. Very cool. So if your team is looking for a developer first APM tool to use, check out Sentry. Use our code to get six months of the team plan for free. Use the code changelogmedia. Yes, changelogmedia, six months free of the team plan. Check them out at Sentry.io. Again, Sentry.io. That's S-E-N-T-R-Y.I-O. All right, we are here with Jake Zimmerman. What's up, Jake? Not much. How are you guys? Doing good. Doing good. Happy to have you here.
Starting point is 00:05:29 This is a requested episode. Always happy when we get to do a show that's... Requested. We know it's 100% on point for at least one person in our listening audience. This one was requested by Max Veldink, who says type checking has been a white whale in Ruby for a long time and very divisive. There's even a built-in attempt in Ruby 3 called RBS that hasn't gained much traction. Sorbet, on the other hand, is being adopted by many organizations, including Stripe, Shopify,
Starting point is 00:05:58 Instacart. His company just works. And he says, I think it's telling that many large Ruby shops are switching to some sort of type safety on larger Ruby code bases. It would be cool to hear from Jake, who works on Sorbet at Stripe around the origin story, what problems it solves there, and how it was like trying to convince pretty curmudgeonly Ruby devs to add type checking into their code bases. So Max, thanks for writing that to us. I agreed. I thought that would be cool. So I reached out and you're here now, Jake.
Starting point is 00:06:29 That's true. Yeah. Yeah. I think all of those things he commented on are kind of what I've lived and breathed for the past five years of working on Sorbet and type checking Ruby. And it's been a wild ride. Yeah. That's the first thing that I noticed was I had heard of Sorbet, but it was somewhat
Starting point is 00:06:44 recently. And I went back to check a little bit on the history. And like you guys were doing presentations in 2018. Yep. And I think it goes back to 2017. Is that right? Like you've been working on it for a long time. The project itself started, yeah, in fall of 2017 at Stripe.
Starting point is 00:06:59 And that's kind of, yeah, one of the things that's kind of set this project apart from a lot of other larger attempts to type JavaScript or type Python. We've kind of just focused on just doing what we need to do and not really going out and trying to sell other people on this vision of what typing in Ruby could be. It's more just been kind of like, here's what we have. If you want it, that's great. If you don't, you can still keep using Ruby. What about inside Stripe, though? Is it more evangelical inside of stripe in terms of like well that's the other weird thing is uh max that in his comment had said like i'm curious to hear like how you know it must have been hard convincing these camaraderie ruby developers but it was the
Starting point is 00:07:40 complete opposite inside of stripe it was the sort of thing where like for years prior to starting this type checker project people were like i, I love working at Stripe. You know, our product is great, but every day I come in here and I have to use Ruby and our code base is too big. I don't understand how anything works. Really just wish there was a type checker. And so we didn't have to convince most of the company. We just kind of had to build the product. That's interesting. Do you think that TypeScript and that move paved the way to some degree that it could be done successfully?
Starting point is 00:08:10 Oh yeah, absolutely. I think a huge part of it was people would switch back and forth between writing TypeScript in the front end or Flow in the front end and then Ruby in the back end and know what could have been the case, what they were missing out on, basically.
Starting point is 00:08:25 So they just asked for it, and they kept asking for it. The lack of types in Ruby is really keen to the prototyping, and I think Stripe is kind of baked. Obviously, you're innovating. Do you think that that's maybe less needed now? You know where Stripe is going. It's a big code base, lots of Ruby. Do you think that's why types in that environment
Starting point is 00:08:46 is welcomed versus, hey, we're proving new ground here. We need to be, at compile time, flexible. We need that flexibility. Yeah, I think people will sometimes say that in the prototyping phase, you care less about types, and in the iteration, long term,
Starting point is 00:09:01 maybe you need more types. I mean, there's a class of people that will break that mold and say, I actually prefer the type checking you know, long term, maybe you need more, more types. I mean, there's a class of people that will break that mold and say, like, actually prefer, you know, the type checking, even when I'm in my prototyping phase, just because it means that you can, if you do want to, like, completely switch out one half of your system, you know that you've, you know, switched it out correctly, because the type checker will catch you. But I think that the biggest motivating factor for us was just at the time, you know, we were getting up to the place where we had hundreds of developers. And even if we were
Starting point is 00:09:28 building new code, it was hard to make sense of it all. We really just wanted to jump to definition to be able to like follow paths of, you know, control flow through the code base and connect things together. So it was more about understanding the code, I would say. It's interesting hearing that because I guess being around long enough, I remember when people would be so excited to be able to work in Ruby on their day job because it was just hobbies for so long and it was
Starting point is 00:09:53 slowly becoming adopted. Obviously Rails really helped that adoption come in when you could actually make money doing Ruby. But we're so far past that point, plus we're at a point where people switch jobs and orgs so much. I've talked to multiple people on the front end side through JS party who have come to a Ruby,
Starting point is 00:10:12 a shop like Shopify or Stripe from something else. Maybe they grew up in JavaScript land doing node apps and stuff. And they're like, yeah, the job's cool, but I have to use Ruby. I don't know Ruby and it's weird. I don't like it.
Starting point is 00:10:24 And I'm like, that's it. That's the drawback don't like it. And I'm like, that's it? That's the drawback is the programming language? And I understand it. But it's just a weird place to be when it's like, that's the part of the job they're not excited about because it used to be that that was so exciting for people to be able to use the programming language they love
Starting point is 00:10:38 and make money. Yeah, it's probably just a relative popularity thing. I think that people's primary programming language tends to be just such a large fraction of how they think and how they approach problems. And if you're used to something, you want to switch that thing is so, you know, different wanted it so apparently there was a desire yeah inside of stripe for something like this but how come you and how you've been working on it for a long time before the show you said you eat drink and dream i love that you said something along the lines of sorbet is all you think about so here you are five years later still just thinking about that all day why you and uh tell the origin yeah yeah uh so i mentioned it started in kind of the fall of 2017. It started with two people who had been working at Stripe
Starting point is 00:11:29 for a number of years and one person that we had hired from just finishing his PhD working on the Scala compiler. So it was a very small team, a very experienced set of people. They spent about a year building it from scratch. So by the end of that year, they had gotten it to the point where it was able to type
Starting point is 00:11:46 check most of the code at Stripe. It was still kind of maybe only 75% of the code base was opted into the type checker and the other 25% still hadn't gotten around to enabling it. But I started at Stripe actually basically the same time that this project started. So I got to kind of follow the project from my team, just, you know, outside looking in for that whole year. And yeah, when I was in school, I was always just super interested in types and programming languages. I didn't really realize this until basically my last year of being in university. If I had realized it maybe a year or so sooner, it's possible I wouldn't have even joined Stripe and I would have tried to do some
Starting point is 00:12:24 sort of research and maybe go into higher education but it didn't work out that way and so I was just kind of like I knew that I had this passion for types and programming languages but I didn't quite understand like whether there was a way to go from just being excited about it to being able to actually do it professionally but I knew for this whole first year that I was working full time at Stripe that that we did have this team and so I eventually got whole first year that I was working full time at Stripe that we did have this team. And so I eventually got to the point where I was just like, I'm going to regret it for the rest of my life if I never even asked to join the team. So one day I just, yeah, I asked and said, hey, you guys have an opening. Can I come help out? team had been staffed by like these super experienced people that they actually really
Starting point is 00:13:05 wanted somebody who had zero experience so that they, the people on the team could have the chance to, you know, flex their like mentorship muscles and kind of learn what it takes to teach younger developers. And so I was one year out of school. I was working with three really experienced people who had this, basically this mandate to like your whole job now is to train this other person so it was a great environment and again yeah because i already knew that i was kind of interested in it i just kind of dove right in and that's kind of been it we've worked on a handful of different things over the five years whether it's been making the type system better whether it's making the experience of using the type system in your editor better.
Starting point is 00:13:45 We even spent a couple of years working on an ahead of time compiler using Sorbet to actually compile Ruby code to native code. And now we're kind of back focusing on how we can basically just improve the type system, improve the editor, improve the type checking experience. Was that ahead of time compiler? Was that work that ended up being not super fruitful so you went back to it? Or what was the story when you went down that path?
Starting point is 00:14:11 Yeah, the compiler project, it was kind of interesting. It was at a point in time when latency was the primary concern for pretty much every team at Stripe. This was during the height of the pandemic when suddenly everyone across the internet who was running a software company was seeing increased volumes and increased loads on the system. So we had basically just every team working on different ways to achieve latency. And we were just going to take whichever
Starting point is 00:14:35 long-term bet panned out the quickest. So some of those people working on latency were just profiling Ruby code, seeing where they could get latency when some people were focusing on making the database faster. Some people were taking really longer-term sorts of changes, like should we rewrite the core architecture to use a different language? All sorts of different bets across the company. So one of these was the ahead-of-time compiler for Ruby.
Starting point is 00:14:59 And we actually got to the point where it was completely working in production, and it really was just a matter of whether we wanted to continue working on it. And because of all the great work of other teams at Stripe making the Stripe API faster, we got to the point where we didn't quite need the latency from the Sorbet compiler,
Starting point is 00:15:19 and it would have come with its own set of trade-offs. So given all that, we wanted to focus then again on the developer productivity side of having a type checker where we can actually make people writing Ruby code more productive. That's cool. So inside of Stripe then, if you could come up with a percentage
Starting point is 00:15:36 of how much code is sorbeted across the code base, do you have those numbers? Do you know how much? Yeah, I have. It's less than 1% is not using Sorbet. Oh, wow. Yeah. There's kind of various strictness levels to what it means to have Sorbet turned on. So the very bottom level is what we call typed false. And even still, even though it says typed false, it's still doing some kind of sanity checking, which it'll make sure that all of the
Starting point is 00:16:05 classes and modules and constant references in the codebase resolve, and it will obviously like check that your syntax is valid. But then up from that there's typed true, and that's the point where Sorbet will start doing actual type inference on method bodies and tell you if you have any like classical type errors like expected integer found string sort of type errors. And then one level up from that is typed strict. And at type strict, not only will it do the type inference, but it'll require that you put explicit type annotations on every method in your file. And I think we even have that type strict level. So it's like 99% at typed true or higher, but at type strict, I think we're somewhere close to like 80% or something like that. It's the sort of thing where over time people encounter the file
Starting point is 00:16:46 that doesn't have type annotations and encounter the files that do have type annotations and they find that it's a lot easier to edit and understand and refactor the code that has the type annotations. And so they've self-selected to opt their files into these stricter checking levels. That's interesting. Network effects, in a sense, right? Exactly. Like, hey, this file doesn't have this. I want to bring it in there. It's interesting. Network effects, in a sense, right? Exactly. This file doesn't have this. I want to bring it in there. It's good stuff.
Starting point is 00:17:10 It's crazy to have such a project take over, too. In one of the posts, I think it's a 2018 posting, where Sorbet is at now, this is State of Sorbet Spring 2019. It actually says 100% of our production Ruby files are Sorbet-ed according to this. Every CI build in the main
Starting point is 00:17:28 repository is checked by sorbade. You kind of lay that out there, but to put such a percentage there, this is a big deal. You're making developers productive. How does the type checking, how does this really equate to being more productive? What are some of the ways that this comes into play? Yeah, so there's all sorts of different things. I think that really equate to being more productive? What are some of the ways that this comes into play? Yeah, so there's all sorts of different things. I think that the quote that I like bringing up here is the first time that we, so we had built this type checker and it was really just kind of like this policeman just kind of like enforcing that you're not doing the wrong thing. In the
Starting point is 00:17:58 beginning, that's all there was. It was like either your CI check would fail with a big red scary message or it would pass. And that's fine. Like you can get a lot of value out of that. But the first time that we took this type checker and we started building editor functionality and like, you know, kind of typical IDE sorts of features and exposing that to users, that was when people really started to have their eyes light up.
Starting point is 00:18:22 So the first time that we sent an email to the company saying, you can now use Sorbet to get accurate jump to definition. People were telling us like, this is the best Christmas present you could have ever given me. It's July, I don't even care. I think that people really identify with being able to understand their code and use the information that the type checker has to, yeah, just dive into an unfamiliar part of the code base
Starting point is 00:18:44 and have confidence that they're going to be able to figure out what it's doing. Sounds a lot like what Sourcegraph markets do. They call it code spelunking. I've heard Byung-Loo talk about that. Being able to jump to definition and explore code base. Especially if you're moving teams, like Jared mentioned before, if you're moving from one shop to another, you've got to relearn, if not just domain knowledge, but also this built-up code knowledge of how the code base works.
Starting point is 00:19:08 In an untyped world, it's got to be challenging if you can't do that. Yeah, and it might be a problem that you only realize is a problem at a certain code base size. For example, even inside the Sorbet code base itself, it's only ever been worked on by two or three people full-time. The codebase itself is only maybe 100,000 lines of code. But when you get into these codebases where it's hundreds of people over millions of lines of code, and the ownership of which parts of the codebase are owned by which teams is fluid over time, you're very rarely working with the same lines of code
Starting point is 00:19:46 for an extended period of time. And so you're kind of always doing that code spelunking where you're jumping from one place to another. Yeah, that's the part in my mind where type checking gets to be super, super valuable. When I think about programming languages that lend themselves towards type checking and enforcement, Ruby is like on the bottom of that list, isn't it?
Starting point is 00:20:05 I mean, this had to be a monumental task because it's so malleable. It's so self-referential. It has reflection. It has metaprogramming. You can just monkey patch and redefine and change stuff all the time. And despite the warnings of use with care,
Starting point is 00:20:22 we tend to do that when it's convenient. Sometimes we do it just because we can. I know I used to be a young Rubyist who liked to shut off different things that he could do, even if just to myself. Oh, look what I can do. Was this very difficult to build? I mean, are there still ways you could poke a hole through it?
Starting point is 00:20:38 What's the situation with all of the, just the weirdness of Ruby as a language? Yeah, I will definitely agree with you that the kind of dynamism of Ruby is both a huge strength in that it's been what's let communities like the Rails community succeed, but also a big challenge
Starting point is 00:20:56 just because those sorts of, like when you can only understand what the code is doing at runtime, obviously that stands in the way of static analysis. So it's definitely a big problem. And it's And I wouldn't say it's a fully solved problem in Sorbet by any means. That's probably still one of the biggest reasons why you might evaluate whether your company or your code base should switch to using Sorbet and you decide against it. Your team really gets a ton of value out of the super dynamic metaprogrammy sorts of features of Ruby. And Sorbet would, in many cases, ask you to give that up.
Starting point is 00:21:30 It's interesting because Stripe actually started, Stripe has never used Rails, but it has used a lot of metaprogramming in especially its early history. And as people have started to adopt Sorbet at Stripe, it's kind of been this incremental rejection of the metaprogramming parts of Ruby. Part of this is because people see the value, again, that they get all these features, all these, you know, safety guards that they get when people are using type checking in their files. So people will, you know, say, here's my trade-off, I'm willing to put down the metaprogramming and pick up the static
Starting point is 00:22:05 analysis. To dive into some specifics, you can just basically read a network request that the static analysis tool is never going to be able to see. And using the contents of that network request, you're going to be able to define methods in Ruby. You could ask the user for the name of a method to define and define it. And there's nothing that the type system is going to be ever able to do to know that that method name is going to be available to be called. So yeah, stuff like that has its place. And Sorbet basically just gives you escape patches to be able to use that stuff. So again, we were talking about the typed false levels.
Starting point is 00:22:41 If you have a certain file that's using a lot of metaprogramming, you can just opt to turn checking off in that file where it's maybe super metaprogramming heavy and turn it on in the other files. You can also silence the type errors at a specific call site and say like, okay, even if I do have typed true enabled in a given file, this one call site where we're doing a lot of metaprogramming, I'm just going to ask the type checker to ignore that line
Starting point is 00:23:05 so you can kind of weave it into your system where you want the type checking to happen and where you want to be able to use the metaprogramming and each code base or team or individual will kind of make those trade-offs knowing what they're giving up and what they're gaining Are there any facilities in there to outlaw like hey, no method missing, for example?
Starting point is 00:23:27 We're not going to have method missing. Maybe that's not really a Sorbet thing. Maybe that's like a linter. I don't know. I guess Sorbet is kind of a linter on steroids, isn't it? How do you picture these tools fitting together? I think that linters and type checkers are very complementary.
Starting point is 00:23:41 The thing about linters is they're way more heuristic based and so you kind of want the ability to say like i know better than the heuristic in this particular case in sorbet there's the rules kind of apply universally so we are kind of more conservative with what we reject in sorbet like sorbet will not reject method missing because if sorbet rejected method missing anyone who everbet rejected method missing, anyone who ever wanted to use it would not be able to use Sorbet. So in our code base, we do have a bunch of linters. I don't know if we ban method missing or not.
Starting point is 00:24:16 There's probably some method missing in there somewhere. We should explain method missing for those who aren't regular Ruby programmers. So briefly, in Ruby, if you call a method on a module or on a class, and that class or that object of that class doesn't have the method that you just called, there's a method called method missing that you can define, which will then run other code that you have decided that will run in order to do whatever you like. So you can use it to dynamically define a new method. You can use it to run a switch statement and do a bunch of different stuff. You could raise an error. It's just basically a hook for you to write some code in case the method that you called doesn't exist.
Starting point is 00:24:53 And people have used that to do all kinds of things. One of the nice things is to write really nice DSLs and provide like top level keywords that are kind of arbitrary or quasi arbitrary and use method missing
Starting point is 00:25:04 in order to call them. But as you can imagine, you can also do some gnarly stuff in there and it's difficult to analyze because it's not defined until runtime. Yep. So method missing is definitely one of those kind of tricky parts for Sorbet to analyze, but it's far from the only one. We do have plenty of lint rules that we turn on to basically say, this is okay, this is not okay. And yeah, kind of guide people into having the most success when using survey. This episode is brought to you by our friends at Drada.
Starting point is 00:25:50 Automate and accelerate your SOC 2 compliance, your ISO 27001 compliance, and many, many more compliance frameworks. With a suite of more than 75 integrations, Drada easily integrates with your tech stack through applications such as AWS, Azure, GitHub, Okta, and Cloudflare. And countless security professionals from companies including Lemonade, Notion, and Fivetran have shared how crucial it has been to have Drada as a trusted partner in the compliance process. They have deep native integrations that provide instant visibility into a security program and continuous monitoring to ensure compliance is always met. Drada allows companies to see all their controls, easily map them to SOC 2, ISO 27001, and many other frameworks to gain immediate insight into framework overlap. They are the only player in the industry to build on a private database architecture from day one,
Starting point is 00:26:51 meaning your data can never be accessed by anyone outside your organization. It is time to say goodbye to manual evidence collection and hello to automated compliance by visiting drada.com slash partner slash changelog. That's drada.com slash partner slash changelog. They are bringing automation to compliance at Drada speed. so one thing that max brought up is like a first party i I guess, Ruby official types, which he says in the works. I don't know much about this.
Starting point is 00:27:47 I'm sure you probably know a lot about this, Jake, just from being in the community. Tell us about that, how it relates to Sorbet. Are they wildly different? Are they similar? Could they adopt Sorbet if they wanted to? He says it's divisive, so I'm sure there's lots of opinions as well
Starting point is 00:28:02 about this topic. Yeah, I think it's mostly divisive just because typing in general is divisive so i'm sure there's lots of opinions as well about this topic yeah i think it's mostly divisive just because typing in general is divisive in the ruby community mostly right not like a specific implementation that's going on in the elixir community right now as well is they're talking about types for elixir and that's divisive because same exact reasoning yeah and so obviously as someone who works on a type checker and who's been interested in types for a very long time i'm super biased biased in favor of the typing side of this. And, you know, I hold the view that types will always win in the long term.
Starting point is 00:28:32 But so you're going to get the biased view here on the state of typing in Ruby. I don't even think Sorbet was the first attempt at building a type checker for Ruby. There were a number of research projects specifically. I remember a couple by the kind of like research projects out of the University of Maryland. I think there was also one other type checker that was built by a person by the name of Sotaru Matsumoto out of Japan and it was called Steep. And so then there was one other that was kind of like a very hobby project built by someone at GitHub in their personal time. So Sorbet kind of started as this just one more type checker sort of thing. So it's always been the case that people have noticed that Ruby didn't have types built into it and kind of decided on various ways to add their own. Eventually, I think that the popularity of Sorbet and the kind of backing of
Starting point is 00:29:25 having such a large company like Stripe and Shopify behind it meant that the Ruby core team was more willing to consider what a first party typing support would look like. So we actually have met multiple times with the Ruby core team. For a period of time, we were meeting with them monthly to kind of talk about what the state of typing in Ruby would look like. And over time, it became apparent that the design constraints that we were going to be working under would be no syntax changes to Ruby itself. Partly this is because Ruby is already syntactically very complex. Parsing Ruby is already hard.
Starting point is 00:29:57 Adding more syntax in service of type annotations would have been just challenging on its own. But also, Mats's the person who created Ruby and still has a very significant, you know, influence in what features get added and what don't was pretty partial to keeping type annotations out of the core syntax. So that meant that we were kind of focusing on having annotation files that lived alongside the Ruby source code. So you kind of have this split between like header files and source files that you might have Ruby source code. So you kind of have this split between like header files and source files that you might have in C and C++. So that comes with
Starting point is 00:30:30 its own trade-offs. Some people will say that that is already a non-starter for them, that no matter what syntax you choose for these like definition header files, that it's already too divisive, like it's already going to not work for them and cause a division in the community. That's, I think, a valid concern, but let's just press forward and say that we're fine with having these annotation files. The next thing that you're going to run up against is, do you use the same syntax as Ruby in these annotation files, or do you invent some completely new syntax? So Sorbet had one of its design goals was to be backwards compatible with the syntax of Ruby. And so all of the Sorbet type annotations are actually just a Ruby DSL.
Starting point is 00:31:11 So there's no transpilation step that you need to be able to use Sorbet in your codebase. It's just kind of the magic of, again, the Ruby metaprogramming. One of the benefits that you can get is you can define these ad hoc syntaxes, and they're backwards compatible. So Sorbet already had this type annotation syntax that was valid Ruby code. And to make these kind of header files, these definition files, it repurposed that existing syntax. So you only had to learn one way to declare the type of an array. You only had to learn one way to declare a signature for a method, to declare an interface, to declare abstract methods, all these sorts of things.
Starting point is 00:31:48 The fact that they lived in the source code of a Ruby file or in some file alongside was just a preference for where you want types to live in your code base. But I think that the problem with that is that by defining types in this DSL syntax that we had invented ourselves, it was kind of clunky. Like we had to go to kind of great lengths to be able to choose syntax that was backwards compatible with this, you know, what we could build a DSL out of. So at the same time that we were working on defining these separate files, we came to the realization that we don't have to be backwards compatible with Ruby in these new files, we could just throw everything out the window and design type annotation syntax that would be a little bit more elegant, but not necessarily fully
Starting point is 00:32:34 compatible with existing Ruby code. So that was the approach that we ended up taking that eventually standardized as what they call RBS files, Ruby signature files. And yeah, they just have a completely different syntax, but they're a lot less verbose than Sorbet annotations. So at the end of the day, though, they are just annotations, and Sorbet could one day just parse them and understand the annotations that are in them. I think that that's mostly just been,
Starting point is 00:33:01 we haven't quite gotten the feedback that people would really absolutely love to use Sorbet. But also like the one thing holding them back is whether it parses these RBS files versus the annotation files that Sorbet supports. So we've been focusing on building features for the people who are using Sorbet. And those people are asking again for things like better editor tools or better type system features. So that's where we end up spending our time. So it's kind of more just like not a fundamental separation, but rather just like it would be work that we have to do.
Starting point is 00:33:33 And we haven't yet found that it bumps up to the top of the list. Okay, good explainer of the state of things, at least from specifically on the Sorbet side. What about on like the Ruby Lang side with these RBS? Is it going to happen? Oh, it's already happened. They shipped these annotations in this format in Ruby
Starting point is 00:33:53 3.0. It's shipped in public and you can just use Ruby 3.0 plus and annotate your Ruby with these RBS files and there's just a built-in type checker into the language? So it's still, you have to pick and choose your
Starting point is 00:34:11 third-party type checker. The annotation format is just Okay, so it's not like built-in then. It's just spec. Exactly. So probably the most popular type checker that uses these annotations is the Steep type checker, which I mentioned earlier. There's also a handful of other tools that consume them. It's just that Sorbet kind of doesn't, and maybe that's the biggest point of division,
Starting point is 00:34:35 is that we haven't gone to the work to parse these files. Is that just the nature that it's open source and you've got other things that are more important? Obviously, it's not that you don't want to it's like eventually you might. Yeah, exactly. So for example the sorts of things that we would have to stop working on right now are we've made a number
Starting point is 00:34:54 of improvements to just the core type system for like what you can actually express in the type system. We've made improvements to how fast Sorbet is all sorts of things like this. And so we regularly go and ask people whether that's in the open source community or people using Sorbet at Stripe, hey, what's the thing that you wish existed the most? And it's always something else.
Starting point is 00:35:14 I guess, why wouldn't it just get built in? That's what I don't understand. I guess maybe you could say, well, RubyGems wasn't built in either for a really long time and eventually gem became shipped with Ruby and so this would be a similar circumstance maybe like they want a bunch of tools to be able to do this and it just seems like if
Starting point is 00:35:36 they were if they being Ruby core team was like super committed to the types that they would maybe this is just step one and they're going to do it eventually they would do this and they'd say and download Ruby 3 and it's type checked. Yeah, I guess one of the benefits of having it be this third party gem is you can iterate on it and release new versions independently of Ruby versions. So Ruby kind of famously releases a new version only once a year on Christmas. But if you wanted to add a new revision to the RBS spec
Starting point is 00:36:07 or standard or parsing libraries for it, having that be in this extra gem that you'd have to opt into makes the release process a lot easier. Good point. You've obviously thought about this more than I have, Jake. And of course, there's lots of different parties involved in these kinds of decisions. It's got the wrong name though, Jared.
Starting point is 00:36:26 What's that? That's why it's not being adopted by the core team. It needs to be called Type Ruby or something like that. Oh, Sorbet? Yeah. What do you think? Sorbet is a cool name, man. It is a cool name,
Starting point is 00:36:35 but I just wonder if it needs to be TypeScript-like. Take a page from the TypeScript book and it's got to be Type Ruby or something. I don't know. I'm not saying it's a wrong name. I'm just making a joke. Again, I think one of the other things that has set apart Sorbet and TypeScript is just the amount of evangelism that has been put into each project. I think that Microsoft in general is just really good at building products
Starting point is 00:37:01 for developers and evangelizing them. And Stripe as a company does that as well. Obviously Stripe is an API company and evangelizes their API, but it's never been the case that Stripe really evangelized Sorbet. Just having popularity and community enthusiasm behind a project would be the tipping point behind maybe more first-party integration with Sorbet. We're kind of fine with the way things work now.
Starting point is 00:37:26 We build the thing and we ship the thing. And people who want to use what we've built are completely able to do so. And people who would prefer, we'd prefer to ignore it can. So let's talk about Sorbet itself, like the implementation, the design. I was reading some of the docs and some of the guides, just trying to see what it was like to use. I did notice pretty decent, pure Ruby DSL. You're writing Ruby inside of your Ruby in order to specify
Starting point is 00:37:56 a method signature and that kind of stuff. There were a few phrases on the website that I was like, this sounds fancy because I don't know what it is. Now I'm not a type guy, so maybe people who are all about type checkers know these kind of things. But I read gradual type checking, I read control flow sensitive typing, some stuff that sound like Sorbet features that I'm sure you had a large part in that might be interesting to our listener to learn about Sorbet.
Starting point is 00:38:21 Yeah, absolutely. So gradual type checking is just this idea that you don't have to type check 100% of your code base from day one, that you can opt in at various levels of granularity. That's basically table stakes if you're trying to add a type system to a language that didn't start with the type system. I don't necessarily, there will definitely be people out there
Starting point is 00:38:44 who tell you that this is actually a completely desirable property, even if you're designing a language from scratch today. Again, you're getting the biased type system nerds view. And I think that it's more just like a trade-off that you have to accept if you're adding types to a language that didn't start with them. Because it means that you have these gaps, you'll always have these gaps in the type system where it won't be able to tell you when you've messed up. And so the biggest problem then is actually figuring out and identifying where the gaps are, if that's the state of your code base. Control flow sensitive typing is really interesting. And I actually think that even more traditional languages that don't
Starting point is 00:39:21 have backwards compatibility with untyped programming language could benefit from. And that's just this idea that if you have something that is either nil or, you know, some real type, like maybe an integer or some struct, some class that you've written, that the type of the variable will be aware of all of the conditional branches that you've taken through the code base. So if you start out with something that's either nil or integer, and then you say, is this thing nil? Well, if you use that variable inside of that branch, Sorbet will be able to say, you've already checked that this thing is not nil. So here it's an integer. So TypeScript does this. Most languages that are gradual type systems for existing untyped languages end up building this feature just because there's so much Ruby code out there that's written this way, or so much, you know, existing untyped code out
Starting point is 00:40:08 there written this way, that you get a lot of, like, ease of adoption by building this feature. You don't force people to go change their code base to, you know, be, I don't know, maybe a little bit easier to type check. So it's this advanced type system feature for sure, but it's one that models Ruby code as it exists in the real world and makes it easier to start using the type checker. Okay. What's an example of when that might be useful or some code that might typically hit up against this,
Starting point is 00:40:36 just not knowing necessarily the value being returned? Yeah, so for example, let's say that you are interacting with the database and you try and load some object with a specific ID. You're going to either get back nil if that object doesn't exist, or your ORM is going to give you the model class back. And if you are writing kind of good defensive code, the first thing that you do when you try and load this thing is you're going to ask whether it existed or not, and then you're going to handle that exception case.
Starting point is 00:41:03 Maybe you report an error to the user. maybe you try looking for the object in a different place, maybe you do something else. But in the case where you definitely know that you have it, now you can start calling the methods on your model. You can ask for the user's name or the user's email or whatever fields are on this model class that you got back. So if Sorbet thought throughout the entire method body that this variable that you got back from your ORM was either a nil or a user model,
Starting point is 00:41:30 then it's going to say, I can't claim for sure that you calling these methods on this model exist or not. Gotcha. Yeah, I can definitely see a lot of Ruby code out there like that. Because there's so many like that nil case is just always the edge. That's just like. Exactly.
Starting point is 00:41:48 Causes us to want types in the first place. It's like, ah. But. And so like, for example, this was, you know, kind of famously the Java's, you know, billion dollar mistake was conflating that every type could be null. I think that it's obviously very hard to to make changes to a language as widely used as java is now but it's the sort of thing where like if you could solve this problem um and yeah build control flow sensitive type checking for for
Starting point is 00:42:16 specifically whether a value is null or not i think it would go a long way to making it easier to reason about yeah in java even, whether a value is null or not. So you bring up an ORM, which makes me think about active record, which makes me think about active record base, as it used to be called, like base classes. It makes me think about existing Ruby libraries. One of the huge advantages of TypeScript being so widely evangelized and adopted.
Starting point is 00:42:46 It's like darn near every library ships with type definitions for TypeScript to just work out of the box. And I'm wondering if Sorbet has that kind of momentum, or is there a place where you can go out and say, I'm going to use this Ruby gem, and the gem's already typed by somebody. Yep, I definitely noticed that in TypeScript, it's like most libraries that you pull off of, you know, NPM are already going to work with TypeScript just out of the box. And there's kind of nowhere near that level of support for typing in Ruby gems that you'll
Starting point is 00:43:20 encounter most commonly. Part of that, there's a number of reasons for this. So part of it is like, as a project, we've almost always focused on making it easier for application developers and library developers. We've always taken less steps to making the process easier for them. That's definitely something that would need to change. And partly it's just kind of, we've never gotten around to it. I think that despite the low investment, people have still done it and still publish gems that have type annotations for them. The biggest ones like Rails though don't. And so if you want to be able to use a, you know,
Starting point is 00:43:54 Sorbet in a project that's using like, yeah, ActiveRecordBase or something like that, you're going to need a different approach to be able to type these sorts of things. And so some, the way that that is typically handled in Sorbet is with third-party gems. And so the way that that is typically handled in Sorbet is with third-party gems that will analyze the way that you are using these gems
Starting point is 00:44:10 and generate those annotation files that we were talking about earlier. And so instead of annotating the source of ActiveRecord itself, you would look how ActiveRecord is being used in your code base and generate some annotation files and rely on those annotation files to figure out what the gem is doing that seems somewhat fraught is that pretty reliable at the end of the day or is my spidey sense accurate it's somewhat fraught for sure it's
Starting point is 00:44:34 kind of a question of like how much you're going to push it if you're using the very common cases it'll be fine but if you're trying to do something more complicated especially if you combine this with heavy use of metaprogramming, then it's going to be a little bit trickier. So I think that recently one person in the community, it's actually someone who has been on this podcast before, Justin Sears or Searles. Searles, yeah. He's actually maintaining this mocktail library for kind of a testing library for Ruby. And he has been posting quite a lot in the survey Slack, just about what it takes to get typing added to a gem. And it's been really interesting just because it's exposed all of these, you know, places that we could make the experience better,
Starting point is 00:45:16 just about like decisions for if you want to have type annotations in this gem, should you start with having annotations that live inside the source code and then strip those out before you publish? Or should you put them inside your source code and also have files that live alongside? Should you make it easier for people to just generate the RBIs on their own? Anyways, it's like his experience has been neat because every time he ran into a challenge, he posted about it and asked questions. And it's been kind of eye-opening to just have that experience. Justin, thank you for all of the comments that you've given us.
Starting point is 00:45:50 That's one of Justin's skills is communicating. You know, he's always willing to post those comments and whether they're more or less salty, depending on his mood. Justin likes to... Yeah, he's been quite polite. So I'm sure that maybe that's gone through a filter. But it's been great seeing what he's been quite polite so um i'm sure that maybe that's gone through a filter but um it's been it's been great seeing what he's been working on he's usually pretty unfiltered but he's also a kind person so when you say rbi now is that the same thing as rbs on the other side but it's like yeah sorry that's the name that sorbet uses for these annotation files that
Starting point is 00:46:20 uses a different syntax but for the same goal and then rbi just stands for ruby interface okay so if i was going to provide type annotations for something i would i would produce an rbi or i guess this is what justin's trying to figure out with mocktail is like what do we actually what's our output as a library author yeah so as a library author like you would either have to have sorbet read the sources of your gem files and use that to understand what's defined, but typically people will not ask the source of the gem be type checked because obviously then it's also going to do things like actually read the method bodies and make sure that all the method bodies type check
Starting point is 00:46:57 and that's going to be particularly slow. So having just the interface files will speed things up a bit. Gotcha. Why go RBI and not RBS? Why would you create a whole new world in a way? Well, so it kind of harkens back to the conversation we were having earlier about what syntax do you want in these files? Do you want the contents of these annotation files to be the same syntax as Ruby code?
Starting point is 00:47:21 Or do you want them to start from this blank slate where you can design the syntax that you want? So the syntax of RBI files is literally just Ruby files with no method bodies. So if you wanted to annotate a method, it's the same syntax in a Ruby source file as it would be in a Ruby interface file. Whereas RBS is this streamlined syntax that you plus the Ruby team kind of collaborated on.
Starting point is 00:47:43 Is that correct? Exactly. In defense of the RBI syntax, I think that one of the things that's a lot easier about it is you don't have to kind of switch between two type systems in the docs. So if you see a type annotation anywhere in Sorbet's docs, it's completely valid to put that both in the Ruby file
Starting point is 00:48:02 or in the RBI file versus having to learn two type syntaxes if you're trying to use Sorbet with RBS files. Does Sorbet run faster with RBIs than it would just in the source code? Or does it not matter? It's really just a function of how many bytes Sorbet is reading. If your source files are really long, then it might slow down a little bit just to parse
Starting point is 00:48:25 through and get the actual annotations out. The crazy thing, though, is just how fast Sorbet actually is. I have gone on record many times and claimed that Stripe's Ruby codebase is the largest. Obviously, I haven't seen every Ruby codebase in the world, and no one has contested me on this point. So I'm going to go forward and continue saying this until someone corrects me that Stripe's Ruby codebase is the largest Ruby code base in the world. Bigger than GitHub.
Starting point is 00:48:48 Oh, by a long shot. And the nice thing about this, if you are a user of Sorbet, is Sorbet will, like, the amount of time that it takes to type check your code base will never be longer than like the slowest code base to type check. So you kind of like benefit from, someone will always encounter performance problems before you will. And that someone will be Stri like benefit from someone will always encounter performance problems before you will. And that someone will be Stripe. That someone will be Jake Zimmerman. Yeah. So that's kind of why a large part of the work that we end up doing is just optimizing and optimizing. One of the fun projects that I got to work on last year was making Sorbet more incremental. So the entire history of Sorbet,
Starting point is 00:49:27 if you needed to run Sorbet in your editor, it would basically just retype check the entire code base. And it was fast enough. Like it would be a little bit slow. You would be able to see when it's doing this retype check operation, but it would only maybe last a couple seconds. And that's fine. That's actually like most of the time fast enough.
Starting point is 00:49:44 Eventually the code base got to the point where that wasn't fast enough, which meant that we had to do some work to make it faster. And the way that we did this was just being smarter about not doing work. Basically we would figure out the contents of any given edit and say like, okay, well we can actually tell that in this edit, only these definitions have changed and then do some really clever things to not have to retype check the entire code base. So it's those sorts of optimizations that personally I find really fun and also people benefit from
Starting point is 00:50:11 that the code base will never get to the point where it's super slow to type check because we've found the problem, fixed it before it ever becomes a problem for anyone else. Stripe is bigger than Shopify. Yep, Shopify, I think. He's saying this like so unequivocally. He's like, yep.
Starting point is 00:50:26 I know Shopify's codebase is one of the codebases where I have actually very exact numbers on how large that codebase is. Because they're using Sorbet. Yeah. They're also one of our closest partners that we collaborate with on improving Sorbet. They've made a number of contributions themselves
Starting point is 00:50:42 and we meet regularly with them to figure out how we could be making Sorbet better. So that's kind of like one of the things that I'm always worried about is like, well, what if, you know, the performance is getting out of hands on other people's code base and I'm not able to even see what the problems are because I can go profile our code base and see what the problems are. Is Twitter still Ruby or is it still a real shop or what? I don't think Twitter is Ruby anymore. I think they use Scala, a lot of Scala. Scala and maybe some other languages at this point.
Starting point is 00:51:10 They all got them too much, I guess. Is Stripe bigger than Basecamp? Probably is. That's one of the ones I don't know of, but again, no one has reached out and told me otherwise. All right, listener out there, if you have a code base larger than Stripe or you think it's larger,
Starting point is 00:51:24 then you need to let us know so we can prove Jake wrong. How many lines of code roughly? Yes, I wrote a blog post on the Stripe engineering blog in May of 2022, I believe. And the code base size at that time was 15 million lines. And that was a year ago, roughly. That was a year ago. If you think you can beat 15 million lines, I'd be very, very curious to hear. Now, I also want to express my condolences for having to work in a 15 million line code base. Is lines of code the best way to quantify it, though?
Starting point is 00:51:54 Wouldn't bytes be better? Yeah, bytes would be better, for sure. I mean, you could have a long or a short line, right? Yeah. If you have millions of short lines, then I have half a million really long lines. Maybe I win. Yep. No, absolutely. Bytes, like, if I have half a million really long lines. Maybe I win. No, absolutely.
Starting point is 00:52:07 If I've sniped you enough, you dear listener, into let's compare our codebase sizes, I will try and ask if you can find the number of bytes. It's usually the tools that report codebase sizes are easier to measure lines of code for whatever reason. So that's usually the kind of like...
Starting point is 00:52:23 That also makes for nicer headlines in blog posts. Right. Survey has this many bytes, or Stripes code base has this many bytes, doesn't quite have the ring to it that lines of code does. Right, LLCs are better in that case, yeah. But if it's going to come down to it, we'll go byte for byte.
Starting point is 00:52:37 That's what you're saying. We'll definitely do that. Okay. If you're comparative on lines of code, let's go byte to byte. Yeah, exactly. Okay. Cool, man.
Starting point is 00:52:46 So I guess the only thing that I'm left thinking is, what is the user experience? Like, let's just say I have a 12 million line Rails app out there, or maybe even a 16 million line Rails app out there, and I'm thinking Sorbet might be for me. Like, how do we opt in or incrementally adopt? What does it look like day to day to adopt it and use it? Yeah, so the steps to adopt it, you can just go to sorbet.org
Starting point is 00:53:09 and there'll be instructions there. The instructions will basically ask you to install a gem. There's actually two gems. One of them is going to be the static type checker that'll report all the type errors in your code. And one of them is going to be that runtime library that lets you use the DSL for annotating type syntax.
Starting point is 00:53:29 So you add these two gems to your code base. You don't even need to write any annotations out of the box if you don't want to. And you can start type checking it. It'll probably report a bunch of errors on your code base. You can either fix those errors or you can turn off the type checker in those files. And that's that. The thing that you're going to want to do is as quickly as possible, get it to the point where every file is at least typed false. So if you have any files that don't have valid syntax or that
Starting point is 00:53:53 have constant names that Sorbet doesn't know about, there's various ways to fix those errors. But that's kind of the baseline. It's getting every file to be able to type check at typed false. And from there, you can now start using Sorbet in CI and making sure that it continues to type check. You can start using Sorbet in your editor and take advantage of all these jump to definition features. And then gradually, again, opt individual files into stricter levels, start adding type syntax to the methods that you care the most about. And that's kind of
Starting point is 00:54:25 it. Yeah. What does the editor support look like? So there's a VS Code extension that you can install and it'll automatically figure out where Sorbet is installed in your code base and how to run it. And it'll show you the errors and, you know, all of the fancy VS Code features will be wired up. If you don't use VS Code, the editor support is powered by a language server protocol server, and it'll work with any editor client that supports language server protocol, which is most of them at this point.
Starting point is 00:54:55 I thought that might be coming, because I read that you're a Vim guy, and I thought there's no way Jake's not going to have support for his favorite editor through some sort of fashion. Yep, no, it works completely fine in Vim over LSP. What about tracking adoption? I see there's two documents here in your docs, adopting Sorbet, which is outlined as you mentioned, then you also have tracking. How important is it to track adoption when you begin
Starting point is 00:55:19 to incrementally bring it in? Who's tracking the adoption? I'd say that the tracking adoption, the metrics one, is more focused for larger companies that are going to be staffing the effort to add types as a proper project. The nice thing is you want to give other stakeholders at your company visibility into the progress that you're making. And there's various ways to ask Sorbet to report how much coverage there is in a codebase so that you can keep people involved and in the loop. The first thing you asked me was,
Starting point is 00:55:48 how many files does Sorbet have type-checked in Stripe's codebase? And yeah, it'll print those out so that you never have to be in the dark about how much progress you're making. I also see TypeScript versus, I guess versus, or comparative to Sorbet as a document. I'd imagine since you all use TypeScript on the front end and then on the back in Ruby obviously this Sorbet type checker, you're
Starting point is 00:56:12 wanting to keep the mental gymnastics to a low so what is this document outlining? If you're familiar with TypeScript you should be somewhat familiar with the way Sorbet is doing are you trying to mirror a lot of what they've done well? I think that doc is one big table that kind of like, if you know this type system feature
Starting point is 00:56:28 and the name for it in TypeScript has this name, here's the corresponding name in Sorbet's type system. Because again, people are way more familiar. Like for a lot of people, TypeScript is people's only experience with the typed language, especially these days. So kind of anything that we can do to make it easier for people to onboard, to survey and understand what names we've chosen for various pieces of the type system
Starting point is 00:56:52 is what that doc is trying to provide. Earlier in the show, you said, I'm going to paraphrase something to the fact that types will win in the end or it's a type world. But restate that and give us the synopsis of why you think that's true i just uh yeah part of it is just a fanatical belief and part of it is i just live and breathe the benefits of type checkers every day and especially yeah once you get to the point where you can't you can no longer hold the code base in one person's head where you have to start collaborating on a code base with more than one person which is almost all code bases that do anything interesting these days having a type
Starting point is 00:57:29 checker to offload the burden of understanding the code and keeping track of relationships between various files and data structures and all these sorts of things is you know super valuable so just uh again we kind of talked about this at the beginning where the language that you use changes the way that you think and changes the way that you approach problems. And languages with type systems, I think, give you such strong vocabulary for how you can structure your thoughts. Did you say types will win in the end? What was the exact phrasing? Give me, lay it down hard. We're trying to name this episode.
Starting point is 00:58:04 We're trying to get your mail down so we can name it that yeah let's uh i mean now that i know i'm on the on the book for figuring out what it is i i will say like yeah types will win in the end just because they're so much more yep this kind of harkens back to my schooling days where i had professors who were super fanatical about types and they kind of instilled in in this kind of like going to church and hearing your preacher preach about whatever gospel just kind of preaching about the values of types so yeah types will win in the end sure there you go all right last question for me you are a type fanatic working in a dynamic language which you seem to have much respect for at least on display
Starting point is 00:58:46 and you have a cool job so surely you want to keep it but if you were to not have to use Ruby like if you were just like Jake Zimmerman start from scratch surely there's a programming language you like better because of the type side of things like what would you be working in would it be something
Starting point is 00:59:01 so when I was in school almost all of our classes were either in C which is just everyone should learn C at some point, or they were in this language called standard ML. Standard ML is a very not very widely known language, but it was kind of one of the first languages to really pioneer algebraic data types and pattern matching and type inference and all these other type system features that have started to gain rapid popularity in other languages. So I think that using standard ML as a language to actually write code in is almost impossible. There's no libraries for it.
Starting point is 00:59:36 There's no build system for it. There's no way to really collaborate with other people. But a lot of languages have gone to great lengths to copy their features. So I think that the most popular language that has copied the most from standard ML is probably Rust. So I'd probably try and use Rust if it were possible. Very cool. I'm looking at the Wikipedia. Influenced Elm, Fsharp, Fstar, Haskell, OCaml, Python, Rust, and Scala. So a lot of influence, like you said, on other languages.
Starting point is 01:00:09 I guess at the end of the day, Rust will win. Any other questions on your end before we let him go? I'm clear. I almost brought back in cold ice cream and hot kisses because sorbet, but whatever. Don't do it. Jake probably hasn't. Don't do it. Jake probably hasn't heard that episode yet. He's like, what are you talking about? The funny part about the naming of sorbet is I'm not even a huge fan of sorbet. I really like ice cream better. What exactly is sorbet is i'm not even a huge fan of sorbet i really like ice cream better
Starting point is 01:00:45 what exactly is sorbet i think it's more of like a dairy-free alternative to yeah it's like frozen desserts yeah like strawberry usually or it's like uh a snow cone of sorts right similar to that sort that's the other funny part is i don't think it's typically served in a cone but our logo definitely has it with the cone yeah it does now we know what's what's holding back adoption it's just this cognitive overload what is this sorbet thing i think it's a cool name just because it's different and uh memorable it is well that's the that's the half the battle is, I mean, Go, for example, is a challenging language to operate around when it comes to finding information. Because it's just a good name, but poorly named in reference to the fact that everything goes somewhere.
Starting point is 01:01:38 Overloaded. You have to say Golang, which is basically frowned upon by anybody who writes Go daily. Like Golang is not part of their lexicon at all they have like weird rules around they do like just social norms like you can type go lang but you shouldn't say go lang i'm like i don't know all these rules people there's a definitely a similar problem with sorbet where if you try and search like sorbet thing that i need to search for half the time it'll just show you like recipe sites you're gonna get some frozen sherbert or whatever it is well you do you'd land sorbet.org which is a sweet website considering
Starting point is 01:02:12 you know 2017 most websites are were taken by then but just one single word got the.org so i mean that's good yeah yeah it was definitely uh i was excited to get that one just a lot of there's actually like quite a few good domain names out there. It's just kind of a question of how much you have to pay for them. But luckily it wasn't a personal project. It was a Stripe project. So what looks expensive for me looks a lot cheaper for Stripe. Good point.
Starting point is 01:02:36 Adam, we should start some Stripe projects. Get some good domain names. All right. We're bike shedding the name. I think that means we're officially done here. Don't you think, Adam? Let's do it. We're done. All right. We're bike shedding the name. I think that means we're officially done here. Don't you think, Adam? Let's do it. We're done.
Starting point is 01:02:48 All right. Thanks, Jake. Jake, thanks so much for coming on, man. Yeah, thank you for having me. So there is a bonus after today's show. So if you're a Plus Plus subscriber, stick around because we asked Jake what it's like to be in such a privileged position, to be employed by Stripe, working on
Starting point is 01:03:10 open source, and having such a significant impact. Living the dream, the open source dream. But if you're not a Plus Plus subscriber, it's too easy. changelog.com slash plus plus $10 a month, $100 a year.
Starting point is 01:03:26 Directly support us. Drop the ads and get a little closer to the metal. Again, changelog.com slash plus plus. Also want to mention a big show coming out on Friday here on The Changelog, an episode of Changelog and Friends. Our new friend, Jeff Geerling, goes deep with us on the state of enterprise Linux, what's happening with RHEL, Oracle Linux, Rocky Linux, Alma Linux, all the Linuxes. Will Red Hat Enterprise Linux remain the open source enterprise Linux standard, or have
Starting point is 01:04:03 they made a move that makes that change in the near future? Time will tell. Tune into that show on Friday. Of course, a big thank you to our friends and partners at Fastly, Fly, and also our friends at TypeSense. Those beats from Breakmaster get better and better with age. It's like a fine wine or a fine cheese, just in audio form. Those beats, they're banging. But hey, that's it. This show is done.
Starting point is 01:04:32 Thank you for tuning in. I appreciate having you here and we'll see you on Friday. Outro Music

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.