EPISODE 1851 [INTRODUCTION] [0:00:00] ANNOUNCER: Doom has seemingly been ported to every electronic device imaginable, including picture frames, lamps, and coffee machines. The meme of "It runs Doom" has become so widespread that it spawned the r/itrunsdoom Subreddit. Recently, Doom made headlines again for being ported to TypeScript. The project involved representing Doom entirely in TypeScript, three and a half trillion lines of, 90 gigabytes of RAM to run, and a full year to complete. Dimitri Mitropoulos is the engineer who carried out this heroic feat. He's also a developer at Vercel, the founder of Michigan TypeScript, and a co-founder of SquiggleConf. Dimitri joins the podcast with Josh Goldberg to talk about what it took to pull off one of the most mind-bending TypeScript projects to date. This episode is hosted by Josh Goldberg, an independent full-time open source developer. Josh works on projects in the TypeScript ecosystem, most notably TypeScript ESLint, the tooling that enables ESLint and Prettier to run on TypeScript code. Josh is also the author of the O'Reilly Learning TypeScript book, a Microsoft MVP for developer technologies, and a live code streamer on Twitch. Find Josh on Bluesky, Mastodon, Twitter, Twitch, YouTube, and .com as Joshua K. Goldberg. [INTERVIEW] [0:01:32] JG: With me today is Dimitri Mitropoulos, founder of Michigan TypeScript, co-founder of SquiggleConf, and all-around interesting TypeScript individual. Dimitri, welcome to Software Engineering Daily. [0:01:40] DM: Hi. Thanks for having me. [0:01:43] JG: Excited to have you on, Dimitri. Just to start off, can you tell us how did you get into coding? [0:01:46] DM: Oh, I love it. Right with the deep questions. I've been programming since I was very young. I had my first email address when I was six, which I think even for these days is kind of cutting edge, but I don't think anyone really knew what the internet was back then. I remember running to school and telling my friends, "There's this website called Ask Jeeves, and you can just type in question. It will give you the answer. It's so cool. Just go Ask Jeeves." And it's like a butler there. My mom was in real estate and I watched her do - they weren't Excel. I think it was QuarkXPress formulas. And I think that was my first real - I hope that's the name of this spreadsheet. It was some kind of like off-brand Excel spreadsheet for technology. And I saw her writing formulas and it was so interesting to me. And I think that was like the first exposure that I had to software engineering. And through my life, I did more and more stuff like that. I got interested in video games, and that interest propelled me to become interested in technology. I started building computers when I was maybe nine or 10 to play, I don't know, Quake III Arena. Or I'm not sure exactly. I don't remember all the games, DOS games in some cases. And that propelled me into high school, where I started doing more and more stuff like that to try to like create programs that would do my homework for me and stuff. And even at college, I started taking paid gigs in college for the university and for people that I knew that they needed help with certain things. Not the point of the podcast, but I think I had some cool projects that I did that taught me a lot. And it never occurred to me throughout all of this time that I could or would be a software engineer in my career. I don't know. We can get into that more if you want, but I don't think it really has a clear start point. I mean, just kind of happened. [0:03:27] JG: What did you think you were going to do before you became a software dev? [0:03:30] DM: I went to college because I wanted to be a Latin teacher. I had a Latin teacher, Dr. Stephen Rosenquist, who was very impactful to my education. And I really looked up to him, and I kind of wanted to be like him. I knew I would be poor. Being a Latin teacher, it's not a lot of those positions left in the US. But I knew I would be happy. And to me, that is the tradeoff that I find myself making very easily, even though it may have dire outcomes. So I went to school for that. But it wasn't long before I realized that actually, to my surprise, the Latin and ancient Greek stuff, the history and all the archaeology and those kinds of things were not that interesting to me. What was more interesting to me was linguistics. I picked up a second degree in linguistics. But in my orientation, I wrote a program that instead of going out to parties and trying to make friends and things, I stayed in my room and I wrote a program that calculated what the fastest way I could take the course curriculum was to get my Latin and ancient Greek degree. And I found out that that's a very bad way to go into it with college because there's a lot of fluff built into the course curriculum. They're expecting you to kind of wander around a little bit. And so I was in the middle of my sophomore year, and I was looking down the line here and saying, "Oh, wow, I'm going to be done with my classics degree. I'm going to be done with my linguistics degree. And I'm still going to have two years left here. What am I going to do?" Because there's ways you can double dip different levels of requirements, major versus college versus university level requirements. And I wrote another program. This time, the program was to calculate what other major I was the closest to having already completed. And it came back speech pathology. I did the undergrad speech pathology, got involved with a bunch of research. Of course, at college, they're dying for - and most majors are absolutely just so hungry for people who can do programming because they need to run experiments. And I learned MATLAB. And they need a lot of help for many professors in different departments, obviously not engineering departments, need people like me to function. I was offered to teach a neurology class to pay for my master's degree and stay on and do research with linguistics research. And I got my master's in speech pathology. I have three bachelor's degrees and a master's degree, none in software engineering. I didn't think of myself as a software engineer at the time, despite all this stuff I'm saying, yeah. [0:05:44] JG: In a sense, would it be inaccurate to say that MATLAB was one of your, if not your first work experience? [0:05:50] DM: That's interesting. Actually, VB was my first, I think, work experience. And even before that, I mean, I was on MySpace making websites before Facebook was a thing. And I wish I had screenshots of some of these websites, in those days, because you could depend on the screen resolution. I think people don't understand how terrible responsive design has been for website design. Because if you know how many pixels exactly the screen resolution is, you can make really engaging experiences. Like video games are today, actually, I think it's like way they are, they're very engaging. They don't have to be responsive though, so they can make really cool stuff. But anyway, yeah, I think that was one of the beginning things. But I did other stuff too. [0:06:29] JG: Okay. How did you then transfer from linguistic speech pathology and so on into software development as a career? What was that first job or internship like for you? [0:06:38] DM: Well, I graduated and I hit a career impossibility. Basically, it's a whole other topic, but speech pathologists do a lot of things and it's a bit of a strange field in that way. And one of the things they do is work with people who have traumatic brain injuries and kind of very highly medical linguistic problems in a clinical setting, like a hospital setting, and I wanted to do that because I have my linguistics degree. And I'm a very good candidate to do that kind of work. But the way it works in that industry is you're expected in large part, it's not true for everyone, but most people are expected to go work in a school for 10 years. You're supposed to climb the ladder. And then like after 30 years of experience, then you can go have those highly sought-after jobs in the hospitals to do that kind of stuff and do research and those things. But I just wanted to start there. So I succeeded a lot in my life by forcing my way through, and I failed so hard to get the jobs that I wanted or the job that I wanted. And yeah, I went broke. Basically, I had like - I don't remember the exact number, but it was like maybe $200 or $300 left in my bank account. And a friend of mine said, "Hey, Dimitri, here's the deal though. I'm a software engineer, and anytime I have a question, I ask you and you seem to know the answer. It makes me think that you might be able to do this. I know you want to be a speech pathologist and you're very excited about this, but what are you going to do next week? You need money, and it takes time to get a job and get on the payroll and all that. Just come work with me temporarily and make some money. And then you can keep applying for jobs as a speech pathologist and do whatever you want to do." That's what I did. Visual Basic. That was VB, all VB, VB6. That company embraced Visual Basic before .NET happened. And so it was all Visual Basic and COBOL, where the two languages mostly that we used. [0:08:21] JG: How many years ago was this? [0:08:22] DM: I think it was like 2013. Yeah. [0:08:25] JG: Okay. Wow. You've been doing this temporary side of programming for over a decade now. And now you're at Vercel. Is that right? [0:08:32] DM: Yeah, yeah. It's a long arc. [0:08:35] JG: What do you do at Vercel? [0:08:37] DM: Well, a lot of things. One of the things I'm proudest of that I am excited about is I've worked on Turborepo. I love monorepo stuff in general. That's been fun. Right now I'm working - it's funny. I realized I don't think I can say what I'm working on actually. I'm working on a new thing that Vercel is doing. It's not like a huge new product. It's just a new piece of functionality within the offering that I think is very exciting. I can say it's something different for Vercel. I think one of the reasons people like Vercel's products is there's kind of like a way to do things, like a way to move quickly in the Vercel ethos about pushing to production and just having things being really fast and really immediate. And I'm doing something that it's a different venture for Vercel as far as like the philosophical side. And I'm excited to be at a company that's figuring out how to make a product that doesn't just suit startups, but suits a wide range of different use cases that may have different needs than now, now, now. I don't know. Maybe that's too big of a hit. I'll find out if I'm fired. I won't be. I'm just joking. [0:09:35] JG: Once this podcast releases. I do want to talk about that a bit just to prep us for talking about Doom and TypeScript, the banner of this episode, because you've been very passionate for a very long time. It's very clear from all your activities and your posts online about dev tooling. And now you're working at a company that in many ways is largely a dev tooling or dev tooling adjacent company. What is it about working for, or with, or around developers that excites you so much? [0:09:58] DM: Yeah, easy answer. Actually, this is a great segue. Maybe you don't know it, but that ties so well into the speech pathology stuff that I was saying a second ago. One of the reasons I think I was excited to work in that field is because when you work with people who are experiencing a traumatic brain injury from a car accident or something and they lose their ability to speak or - not all stories are success stories. There's definitely a heartbreak there. But the feeling of helping people is so exciting to me and I enjoy it so much that it drives me to do a lot of things. And I feel like I'm missing that a lot as a software engineer. I've never worked for one of these kind of companies, but I have friends who have worked for large companies and they tell me that you wonder whether the code you're writing is going to be used in a drone strike later. You wonder where this is all going 10 years from now. Because you leave the company but the work you did stays there with the company and you don't have control over what it does next. And that sense of hopelessness is hard to overcome, I think, for a lot of people in software engineering. But when I work on DevTools, I feel the feeling. It's a bit similar to the feeling I got from working with kids, I think, is the best example. I worked in a preschool for a while. It's one of my placements as a speech pathologist. Despite not wanting to work in schools broadly, I did quite enjoy working in preschool because you see the growth over a very short span of time, and you see someone go from zero to hero over just a few months with you working with them. When kids are very young, they can learn very quickly some things, and if they have a professional that knows the tricks to teach them. And I think that DevTools is a lot like that, that you end up taking a person who maybe didn't feel empowered to be able to do something like make a website or publish their thing to the world. And you give them this tool that kind of walks them through it and suddenly they're able to do this amazing thing and the empowerment that they get from that is so cool. And you may not even know them. That's a way in which software engineering is so exciting to me. You may not even ever know that they exist ever. And they're just out there. And it's cool to go and meet people in person and hear stories. But I like the idea that there's this force multiplier when you work on something like DevTools that you're changing the world in some kind of positive way that, yeah, I mean, the other side of the fence is true, to go back to the drone strike thing. They could be writing drone strike software. I guess I don't know. I mean, both sides are possible. But I think in large part, I feel like I'm putting smiles on faces when I work on dev tooling. And it's a lot more smiles when you're working on something systemic that everybody uses rather than making a product. There's lots of products I could work on that end users use directly and I would feel good about that, but it just feels so much bigger on dev tools. [0:12:28] JG: Let's finally get to it. How does this all relate to Doom and the TypeScript types before we actually talk about what that is, how did you, and why did you do this thing? [0:12:36] DM: How does this all relate? I mean, I don't know. I guess it doesn't. It's a pointless project, I think, in a lot of ways. There's no reason to do a thing like this, necessarily. And it's a love of the game, I guess. I think tinkering has a lot that it can offer you as a professional. And I learned way more - I mean, I said it in the video, the announcement video, but I learned more working on this project than in the prior 10 years, working very hard professionally, I might add. I mean, I tried to push myself quite a lot at work and I've done some great things I feel very good about. I've worked with some really cool teams, which I feel even better about. But nothing compares to what I personally learned working on a project like the Doom and TechScript types project. [0:13:17] JG: Sure. When you say pointless, there's, of course, no direct professional point to it. But the actual benefits, the consequences of the project beyond internet fame and amusement is, yeah, that you've learned a lot, that you've built tools that perhaps other people may use. It sounds like it was quite a productive point full project. [0:13:34] DM: It's shocking how often Doom has come up. I'm so glad that it's out now that I can tell my colleagues. Because there were a lot of times at work where they'd be like, "How do you know this? It'd be like debugging some TypeScript performance thing, and I'm just like showing people - I did a brown bag session at my company trying to teach people how to step through and break through the TypeScript compiler. It's kind of like I think fairly advanced, strange thing to do or need to do. And a few people were like, "But -" or even start learning to do something like this. And what I couldn't tell them at the time, but now I can say is I learned how to do this because I had to do it to get Doom to work. And there's lots of things like that where it's not just TypeScript type stuff where there's learning how C works and how to do cross compilation and how to do, I don't know, WebAssembly. I know way more about WebAssembly than I could have ever imagined because I had to implement a WebAssembly runtime from scratch. And guess what, when you're at a company that's doing interesting things, these type of - not just mine, but lots of companies, these things come up, but you may not realize they're coming up unless you have the expertise. And unless you can say, "Hey, wait a second. I see the problem that we're facing and I know a thing that could help with that. Why don't we go take a look?" And there's not really a way to be in a position to make a statement like that at your company to better what the overall company is achieving, other than side projects, as far as I know anyway. [0:14:52] JG: Yeah. We've buried the lead quite enough. Dimitri, I'm going to give you a small time span of about 30 seconds. I know what JavaScript is and nothing else. Tell me what did you do. [0:15:04] DM: Programming languages have a concept called types. You can set variables and the variables have a certain type. Types are like numbers and then programmers have this thing called strings, which is like a bunch of characters, like a list of characters. Well, in TypeScript, you can set a static string as a variable type. You can say this type is only allowed to have red or blue and no other strings are allowed, or the numbers 7 and 13, and no other numbers are allowed, stuff like that. And just based on that, just based on the ability to set a literal type, you can create other types that operate on those types. Now I can say I'm gonna take red, lowercase r-e-d, and then make it all uppercase. I can create a type that will take an existing one and change it. And I made a type that will take the innards, the source code of Doom, if you will, and by type checking it, which is a way that the TypeScript type checker will validate that your source code hasn't done the wrong thing, I made a type that will create a frame of Doom by checking the type. The result of checking the type is a frame of Doom. Just like you can create a type that will operate on lowercase r-e-d and give you uppercase R-E-D, I made a type that will operate on the source code of Doom and return a frame of the screen. How did I do? Was that out of the problem in 30 seconds? [0:16:24] JG: It was a minute, minute and a half, but it's an absurd thing. Just to confirm, there's an old continuous joke people do of "Can Doom run on this?" People put Doom on the TI 84 Calculator and all these microcontrollers and stuff. You got Doom running in the TypeScript type system That seems like an inherently impossible task at first because the type system is not the programming language runtime itself. It's a way of describing types. So how it is possible that you can run a logical piece of C code in a type system? [0:16:54] DM: Well, I think I can answer this with somebody said on - I think it was on Reddit, or maybe it was on Twitter, whatever. Somebody said, Well, all programs need a main function," which is like the entry function that it calls. And this guy may have done most of the work in TypeScript Types. But TypeScript Types don't have a main function. There's no way that he could have actually done it. And the response I gave to that is like I had the same feeling going into this. I never thought this. We haven't gotten into this part, but I think an important thing to mention we can talk about in a second is I never thought this would work. I never expected this would be possible. I was very sure of the opposite, actually. TypeScript types can operate on anything if you can create the abstractions. And it turns out that a main function is just an abstraction. There is stuff beneath the main function. But if you write C, you just don't get to look at it. You don't get to see what's going on, like, "Okay, so there's a main function. But what calls the main function?" Well, you don't see that part. C handles that for you. And an executable, whatever, all the stuff that we have handles that for you. I had to piece that apart as well. That's the way in which to answer your question, that I was able to get something to actually execute is I had to kind of dig into all that and find out how it works, which was news to me. I had no idea about any of this stuff. [0:18:07] JG: But taking a step even further back, you're talking about being able to determine the entry point of an application and how to bootstrap it. But what I mean is logically, when people use the phrase "Turing complete" or "Turing completeness" referring to the TypeScript type system, what does that mean? [0:18:21] DM: Nothing. Turing complete to me means nothing, basically. I think it's a useless concept. And I'm sorry to mathematicians who are sneering at me, but the thing is that there are known Turing complete systems that can't do anything useful, like let's say one plus one, before the heat death of the universe. I think it is interesting mathematically maybe, but I don't really care. And I think one of the things that spurred me to do this project is I felt for a long time that Turing completeness is not that exciting. It's been known for those listening. I think, Josh, you probably know, but TypeScript's type system has been known to be "Turing complete for a while. [0:18:55] JG: Which means? [0:18:56] DM: Yeah, which means that you could theoretically compute anything given enough time and resources. In fact, given infinite time and resources. And by the way, I learned a lot about Turing completeness. There's a very important thing about Turing completeness I never hear people talk about, which is that the definition of Turing completeness doesn't include the ability to loop. I think printf in C, there's printf debugging, printf has been shown to be Turing complete, but the definition doesn't mean that there's a way to have it kind of recurse and do constant loops. It may be required that you have some external force that's constantly pushing at you, saying, "Okay, not do another thing. Okay, not do another thing. Okay, now do another thing," constantly. And that external thing is considered outside the definition of Turing completeness, which I think is like another thing that's kind of baloney, right? I learned that Doom itself is Turing complete. The Doom engine, the Doom game. You can create Turing completeness inside of Doom. And so my proposal, programmers, my proposal to you, stop talking about Turing complete, start talking about Doom complete. [0:20:00] JG: Can it run in Doom? [0:20:01] DM: Can it run in Doom is a way more interesting mathematical observation of a system than whether or not it's mathematically theoretically Turing complete. Because if it can just run one frame of Doom in a human lifetime, I think that separates lots and lots of known Turing complete systems. [0:20:18] JG: There you go. Sorry. That's my rant. [0:20:21] DM: I was hoping to prove this point with a project that I was hoping to demonstrate how - just because TypeScript - the starting thesis is kind of was. Just because TypeScript types are Turing complete doesn't mean that you can do - run a frame of Doom. [0:20:35] JG: Yeah. That was the idea. And then in your video you mentioned that kept you going through the whole thing. [0:20:39] DM: The whole thing. Yeah, I never lost track of that. And I'm not being dramatic. I genuinely never believed at any point that it would work until the very second that it was on the screen in front of me and I couldn't deny it anymore. [0:20:52] JG: Sure. We will cover a lot of the stuff you did in the type systems such as making a WebAssembly runtime, all the tooling you wrote around it. But for folks who are working in TypeScript day-to-day, perhaps not building a video game, but describing their rich functions or making third-party utility libraries, what are some of the TypeScript type system features just within TypeScript that you think folks would be most interested in or find useful? [0:21:15] DM: About the Doom project? [0:21:16] JG: Just TypeScript in general. [0:21:17] DM: Oh, TypeScript in general. Okay, sure. I mean, I think that TypeScript has a lot of dangers that you can run into. I think that largely, there are very important things that you can do, like strict mode is one that I think some people miss in the very beginning. TypeScript without strict mode is not TypeScript in my mind. It's some kind of like compatibility mode for migrating projects. You really need to have strict mode on. Go into your TS config and look for strict true in that or a TS config that it extends from. It's very important. I think that the larger point with TypeScript is not about making it perfect. I think some people get very hyper-focused on - there's this concept of type soundness and making 100% sound programs. It's not all it's cracked up to be. And if you're not sure about that, you should try writing Rust. I love Rust. I would describe myself as a Rust shill. But Rust makes it very hard for you to do scrappy things, to just try out an idea. It's like not very easy to do because it puts a lot of constraints. We don't want TypeScript to be something like that, I think. What are the features? I mean, to be honest, there's not a lot that I think a normal program really requires. If you find yourself writing very long types, and long for most people probably means like 10 line types or something like that or five-line types, you're probably in a position that requires you to take a step back and take a breath and think about what the constraints are that you're really working with. I've seen situations where people try to introduce type safety where it doesn't really exist. And sometimes what you need is like a validator. You need ArkType, or you need Zod, or you need AJV, or some JSON schema, or something. Instead of trying to make a TypeScript type that's like really, really perfect, sometimes you need to just understand that we're working with imperfect systems where, yeah, maybe today the API returns the response you want, but next month the API can change. Someone might change it. You kind of need to write software that can handle that. And I think that's where dynamic programming languages like TypeScript really shine. [0:23:18] JG: Just to be clear, the guy who got Doom running in the TypeScript type system is telling us that in most cases we perhaps don't need very rich, complex TypeScript types. [0:23:27] DM: Basically, in all cases. Yeah, I think I am not a TypeScript type-level programming evangelist, which I think is kind of funny sometimes for people to hear. Actually, I wouldn't even describe myself as a TypeScript evangelist. I think TypeScript should be used in a lot fewer places than it is today. There's a place where it's really awesome, and I would like to see more. But in the frontend, to say it quickly, I think it's the one. But backend JavaScript, I am very much not on the train of. I know that it can work for some people sometimes, but I'm basically not a supporter of using TypeScript at all on the backend if there's any other way to avoid it. It's just my feeling. But reasonable people disagree on this, don't they? [0:24:02] JG: Yes, I do wish we had the three hours to discuss whether and when full-stack JavaScript is applicable, what a full-stack engineer means, perhaps in a subsequent episode. But okay, let's say that I'm on a web platform team, or frontend team, or some such. I'm writing React, or Angular, or whatnot components and I'm finding myself in the position where I have a kind of generalized functioning. It takes in a bunch of different things, maybe a polymorphic component, and it returns something different based on the input. What is kind of your theology of trying to determine whether I should use fancy type system features or rewrite the component in that case? [0:24:37] DM: I think it's situational on a few factors. I can't tell you when, but I can tell you the factors. One of the factors is the team. I think that people who are excited about software engineering, clearly, you and I are, and perhaps people listening to this, I think that if you're really excited about something, some aspect - just to make fun of it, let's use functional programming. Maybe we've all experienced engineers that are really excited about functional programming. Okay? The analogy is TypeScript types. But let's make fun of program - I love functional programming. It's easy. I'm one of the boys. I'm in the in-crowd. So I can make fun of it. What happens a lot is you notice people who are very passionate about advanced features will kind of push it on their colleagues. And this creates an immune response among the team that can sort of reject the input, even if it's the right thing to do. And I've seen this happen with TypeScript types, just as much as functional programming or other things that people get nerdy about and excited about. And I think that looking around you to see how your colleagues feel and if they're comfortable with adding advanced types that do advanced things is highly critical and often overlooked. Of course, you can't know who's going to be taking on the code base in the future after you, but that's one of the biggest factors, I think, is a social one. Is your team down to go down this path. And if not, even if it's probably the right technical choice, you shouldn't do it. I think that's a veto card that you need to be able to pull on behalf of your colleagues if you want to be a kind of leader on your team or you want to make cool software. Another factor, I think, is this general health of the codebase itself. The codebase is not in good health. And we can kind of wax and wane about how to define what that means. It means different things to different people. But maybe it's a performance problem, like you see type checking is taking a long time, or there's lots of TS ignores and TS expect errors kind of overriding the type system all over the place. I think that's a very objective sign of unhealth. If you see that situation, you should try to focus on those things first before adding advanced TypeScript types that do very amazing, impressive things. It's important to level out the code base, because if you haven't done the basics, you don't want to do the advanced stuff. Make sure the basics and the bases are covered first. Has strict mode on, like I was saying before. Don't have any TS ignore or TS expect error in your project, not even one. Even one is unacceptable, I think. Well, the only time when it is acceptable in my opinion is type-level testing, when you're trying to validate that a type that's exposed on your API will, in fact, error. That perhaps is the one, but that's a whole other topic that I think most people are not even aware of. Don't worry about it. But these are the factors. I think the two main factors that I think about when deciding whether or not to use advanced stuff. I try very hard not to bring any of the advanced stuff to work, to be honest, in most jobs that I'm at. I've been doing this kind of TypeScript stuff for a while. And it's usually not a good idea, to be honest. [0:27:23] JG: I have so many follow-ups. This is great. Thank you. Yes. The social aspect, I think, is drastically underestimated. A lot of people will take a look at a problem and think, "Oh, this is the right way to look at it or the right way to solve it." But if your team around you does not know something, the cost of training them all up on this particular solution you want might be significantly greater than the cost of just letting it be slightly incorrect or off in your opinion. [0:27:46] DM: And the cost can be to you socially, not just the cost and the code names. It can also be that people hate working with you because you're forcing them to do things that make them uncomfortable. And of course, there are ways to solve that and give them that comfort and show them. And you can pair program with them and walk them through it. But at the end of the day, if they're not down for the experience, then you kind of have to work with that. [0:28:06] DM: You mentioned an interesting point that there should be no TS ignores or TS expect errors. I have a type that is hard to work with an existing code and TypeScript give me a complaint. I don't have the 13 hours to go fix this one particular complaint in old code. What should I do, Dimitri, instead? [0:28:22] DM: You could use it. I mean, it's a tool. It's there to be used. I mean, one of the things - actually, maybe you don't know this, Josh. One of my only contributions to TypeScript ESLint was I'm the person who added the change to the ban - what is it called? It's called the TypeScript Directive, the thing we're talking about, TS ignore and TS expect error. And I put a thing into TypeScript ESLint where you have to write a description of why you are doing this verboten thing that you shouldn't do. I think the first step is, if you have to do it, you have to do it. I mean, we're here to crack some eggs and make some omelets, right? Sometimes that's how it goes. The best thing you can do first is, in that exact moment, describe why it has to be there, why you think it has to be there. Because you might have missed something and someone might come along later and go, "Oh, well, if that's the reason, actually, that problem doesn't exist anymore." Or, "I know the solution to that." Sometimes these things can sort of self heal by the beautiful nature of working on a team, and you can get a long way with that. [0:29:17] JG: Love it. Yes, that's the ban TS comment rule in ESLint and the allow with description option. Great one. I use that. [0:29:24] DM: Thank you. [0:29:25] JG: Yeah, thank you for contributing. But okay. You also mentioned using strict true. Trying to avoid TS ignore and expect errors, perhaps linting. Before we move on to the rest of Doom and TypeScript, what are some other tips you have for folks trying to write enterprise- grade, high-quality TypeScript on large teams? [0:29:41] DM: You really nerd sniped me here. There is one super unknown feature of TypeScript that I think is absolutely unacceptable to not use for a library or for - basically, I think everyone should turn it on. And it's called Exact Optional Property Types. I'm going to be making some point in the next year probably a video on this because it's one that I think is missed by a lot of people. But basically, without describing what it does, I'll tell you the effect of it. It's a thing that users may turn on and users of your code, your library, may turn on to increase their type safety. But if you don't have it on in your library, there are kind of type conundrums that you can thrust your users into that they can't get out of without lots of kind of nasty workarounds. And if you would just be so kind as to turn it on in your codebase, then people who are not using this feature, which is most people probably, because I think, like I said, a lot of people don't know about it, it doesn't affect them. It's a complete no-op. It's the same for them. But it only increases the life and the experience of users that do have it on and keeps them from having to do very nasty workarounds. And I think, also, it just makes for better software, which is why people turn it on. I guess if I had to pick one, that'd be my one that I wish I heard more people talking about. But that's one of the reasons Michigan TypeScript exists. That's why I started it. And that's why we have people on talking about this kind of stuff is I would love to share those kinds of things as I come across them and hear from other people what theirs are. Yeah, that's my - [0:31:05] JG: Sure. Exact optional property types in TypeScript. What is the definition of that? What does it actually do? [0:31:10] DM: I'll read you the blurb here. Let's see. With exact optional property types enabled, TypeScript applies stricter rules around how it handles properties on types or interfaces that have the question mark prefix. Basically, it's separating the situation where, is the property there or not? It's like one situation in an object. Is the property physically there? And then there's this other weird thing in JavaScript where the property is there, but the value of the property is undefined. Usually, in native, kind of standard TypeScript without this option, this exact optional property types turned on, you can't really distinguish at a type level between those two things. The property being absent is indistinguishable from the property being present, but the value is undefined. But those are kind of different things. If you do object.keys, you're going to get an array back with very different results depending on those two. And it's kind of nice to be - I personally feel - I don't want to say the TypeScript team has done something wrong or something. They're kind of holy to me. I respect them so much, but I personally feel like this should be in strict mode. I think it's no argument that this has to be in strict mode. But it's a little annoying to solve because you have to start thinking about this difference. And in a lot of situations in JavaScript, it doesn't matter. If you're trying to access the property, you'll get undefined back whether or not state A, where the property is not there, and state B, where the property is there, but the value. In either case, if you try to access it, you'll get back undefined in JavaScript. And so it looks the same, and I think that's where this kind of comes from. People are used to it being the same. But yeah, sure. [0:32:47] JG: It's a good point. Back to Doom and TypeScript. We've covered that, just to recap, you are able to write logic in the TypeScript type system. We haven't named the features explicitly, but logical types, and then map types and such. And then we've covered a lot of the real-world uses or areas around how those might or might not be relevant and applicable for teams. But I do think we do, by user demand, need to cover. You wrote a WebAssembly runtime in the type system. What does that sentence actually mean? [0:33:14] DM: Right. The name that people use is type-level programming to describe this kind of way of doing programming where you're just operating only on types. You have types as inputs, types as outputs, types as transformers. So, kind of functions. And basically, I didn't know anything about WebAssembly when I started. Some people ask me, "Why did you use WebAssembly for this? Is it because of this? Is it because of that? Is it because of this other thing?" And the answer is, it was the second thing I tried. I didn't know any better. And I had never used WebAssembly before. So, ignorance. In WebAssembly, you have this concept of instructions. And instructions are very simple, very, very simple units of work, where you say add two numbers together, or subtract this number from that number, or do the bitwise and of these two numbers, right? There's these operations that you can do. And WebAssembly, the Semantics of WebAssembly handles a lot of the higher- level abstractions for you. You don't really have to think about it. There's no arrays. It's kind of surprising to people hear, like, there's no arrays. Well, there aren't. In WebAssembly, it's just numbers, basically. There's not even strings or booleans in WebAssembly's kind of "type system". It doesn't actually have a type system, but it has WebAssembly values, which can be 32 or 64-bit units of numbers. And then you can have these operations that will operate on those numbers. But through lots of abstractions, you can represent basically anything with numbers, right? I can just say, "Arbitrarily, the numbers of the alphabet are these numbers. A is 1, B is 2, C is 3." That'd be an encoding, right? You can create an encoding for lots of things. And then now look, they're numbers. But trust me, bro, they're strings. And so you can create these kind of structures and abstractions. And WebAssembly does exactly that. It builds abstractions one over the other, over the other, over the other, until you can kind of do whatever you want. It's kind of like we were talking about before with Turing complete. It's a very kind of practical application of this idea, but with a lot more knobs and buttons that you can push. A WebAssembly runtime takes as its input WebAssembly instructions. And then it does some work. That's the runtime part. And then as an output, it kind of like returns from a function, right? It's like you have a function and it returns some result. Most of the time in WebAssembly, the result is actually a function that you gave it, that it will give some bite values to. Normally, when you call WebAssembly programs, they just give you back a pointer. And that pointer, you also have access to the WebAssembly memory and you go into the memory and you do something with that pointer. You're supposed to know what to do with that pointer. So it might be a string. So there's this convention. I didn't know about this either. There's this convention called C-style strings where you have the sentinel value, the special value, which is all zeros of byte value. Eight zeros. And you just read from memory. They give you a pointer, you go, "Great." You go to that pointer in-memory, you just read bytes out, you take those bytes and you convert them into known ahead-of-time values because they're mapped in a certain way. That's like ASCII encoding, and UTF-8 and these things. So everybody knows in advance what the encoding is. You take that knowledge, you turn those numbers into strings, you build up the string. And then someday, suddenly, you hit a zero and you go, "Oh, okay, that must be the end of the string. I'm all done now." And then now you're in JavaScript. Now you've converted something over the boundary. And that system is exactly how the type system stuff works, where the input is TypeScript type, which basically just the WebAssembly instructions, but they've been transformed into a form that TypeScript can understand, which is it's stuff that you would think. It's an object where it says, like, "kind add," and then there might be some operands. And then it's just an array of stuff like that. That's the instructions list. The WebAssembly runtime does all the work, and then the result is an object. In this case, is a string. We could just say, a string of a screen of Doom. Yeah. [0:37:12] JG: How long does it take for such a project to come to be? How many hours or how many months of work do you think went into it? [0:37:20] DM: I struggle so much to answer this question. By the way, maybe I should apologize to people who watched the video. There was some debate about. I made this comment in the video that it was like a year of 18-hour days. And some people took that to mean that I repeatedly, without any pause, spent 18 hours of every day. So I basically did nothing else other than work on this for a full year. And I didn't mean that. I wasn't trying to be imprecise, but there were many literal 18 -hour days, and there were many days that were more, greater than 24- hour programming spans, where I would see the sunrise, see the sunset, see the sunrise. It'd be mid-day and I'd go, "I think I'm supposed to sleep now or something. I better step away for a moment." Also, there were times when I was kind of never stopped thinking about this problem. There were times when I was driving for an hour to go from point to point. And the whole time, it's like I was in a daze almost. I'm glad I didn't get into any accidents. I was just thinking about this, like trying to figure out how to solve a particular problem. And so it's kind of consumed me, I think, for quite a while. I never really put it down in a lot of ways. Yeah. But it was start to finish from the day that I kind of had the idea until the video, the announcement video we could say, one of the end points, was a year and a half. But I say a year because I don't want to overestimate. It was a year of very, very constant effort. And there were large swaths of that year where basically no code got written because I would just try things and fail and try things and fail. And I just couldn't figure out how to get past certain roadblocks. [0:38:47] JG: Sure. Let's talk about those roadblocks. How do you actually - you said that in WebAssembly, there's no array concept or strings on top of that. Objects, really. It's all just bytes, bits. How do you work with that in the type system then? How does that actually function? [0:39:06] DM: I don't know. It's hard for me to reason about the pieces. I mean, I think the answer concretely is an extremely, extremely overdone test suite. The real hero of this project is the test suite. Because I, from the very beginning, from the first keystrokes, were tests. I wrote excessive. And I knew they were. But I wrote excessive, excessive tests. I did fuzz testing, which is where you kind of create random inputs and validate them so that you're not succumbed to the things that you can only think of. And I did. Actually, the fuss testing caught a few things. So it was good. But I was really, really careful to be very, very sure about having tons and tons of tests for every single action at every single point. And that became brutal because I actually did have to rewrite the engine three times. Well, the third time was the - I didn't rewrite it three times. I rewrote it twice. There were three versions of the engine. It all uses binary numbers, for example, under the hood. And the numbers are stored as strings. But I didn't want to do that. I just really didn't want to do that. It seems very complicated. And I don't know a lot about binary arithmetic and stuff likeI- just thought there might be a way to cheat and get by without having to do that. Because after all, like I said, all I was looking for is the reason this can't work. If I can find some other core problem that it hits, I won't have to go through all the trouble of doing the binary numbers. I know this is like a non-answer to your question, but I don't think there were any specific things that I can point to say this is the project. Because really what it was is just tons and tons of small building blocks. We were talking about the main function abstraction. That's one of them, right? Figuring out how to call that main function. I spent a couple of days on that and then it was done. And then that's it. I never really had to fix that one again. But there was just tons and tons of little problems that's kind of fanned out. Every time I solved one, it would create five more. And then I would solve those and they would each create five more. And then eventually, if you just keep trucking away, sometimes it just works. [0:41:03] JG: Talking about one of those problems, you have to do some kind of binary arithmetic in this system, right? You're manipulating the numbers used internally to the WebAssembly runtime. How does that work then in types. [0:41:17] DM: The whole engine is built off of three things. And they're very simple things. Number one is the ability to add a character to a string. Number two is the ability to remove a character from a string. And number three is the ability to look through the current values in a string and change them. That's it. That is all I needed to be able to do this. Everything is built off of that. And there's lots of tricks that I didn't come up with that are - it turns out that - and this sounds really funny when you first hear it. It sounded funny to me anyway, that you don't have to do subtraction because you have addition, and you have a way to make a number negative. If you want to subtract, you just add A plus negative B, and that is subtraction. But you didn't actually have to implement some kind of subtraction routine. The subtraction code, that's all it does. It just uses the addition code. And then there's a way to make a number negative. It uses that code. There you go. Now you've done subtraction. How about that? [0:42:21] JG: Beautiful. [0:42:22] DM: I think like that's the concept is like you're kind of looking through. You can imagine in your mind, a bunch of zeros and ones stuffed X to each other in a string. And you're kind of looking through them and doing some kind of work, exactly the way that we were taught to do math in grade school, elementary school. That's one of the reasons the numbers all had to be reversed is because if you're thinking about how you add two numbers together, well, if you have a carry, because you hit the limit of your binary versus decimal, anyway, you hit the limit of - whatever, how many digits you have in the number system that you're counting with, whether it's 10 for decimal and 2 for binary. You go from one side to the other, and it's just how it works. But, yeah. [0:43:03] JG: Okay. Let's take up an example of this then. Let's say you're writing a type to do one of these very foundational pieces of the logic. What is the type taken then? [0:43:11] DM: Yeah. Let's use a specific example. Let's use a four-bit number. 0001. That's one in binary, right? And you have four bits. So 0001. If you want to add another number to that, you would take a second type parameter. You have A and B. So 0001. And then 0001. We're adding 1 and 1. 1 plus 1, we know, equals 2. But in binary, you don't have 2. Actually, you would have to - if you add those, think of putting those numbers over each other, then what you're going to do is you're going to carry. The rightmost digit is going to be a zero now and the next digit is going to be a one. The result is 0010. Yeah. You got it? [0:43:57] JG: Mm-hmm. [0:43:58] DM: What you're going to do is you're going to take A, and in your type you're going to loop through the values of A. The first value of A - now reverse now. Okay. The first is actually to reverse both numbers. So you have to do that. Now we're already into some weird territory because now the number, as far as what the TypeScript is being fed, is 1000. Everything is in reverse now. We're in reverse land. We're in the stranger things upside down. We take that one and we also - inside of it, we nest another loop where we're looping through the characters of B. And then inside of that, we compare values and we make choices. We're going to be fed. There's another function that just gets one character at a time from each side. And it's going to, in the beginning, get the number one from A and the number one from B. And then it's going to say, "Okay, I know, I've been told, I've been pre-coded to say that when I get those two -" there's only four combinations anyway. I actually just made a lookup table of the results. I'm going to get those two values, I'm going to return this result. I return a zero, and then there's some special way that I can communicate that I have a carry. And then the greater loop that's going to return, and the greater loop is going to go, "Okay, great. I have my first digit, it's zero. I'm going to recurse, I'm going to loop again, but I'm gonna tell it that, from the last time, I had a carry." And so next time it's going to go through, A is zero, B is zero, but it has a one because there's a carry from last time. And so it knows how to work with that. And it will return, it will pass that to the function again, same one, and it will return the value one. We did zero. Now we did one. We'll do the next part again because there's no carry and both values are zero. So, zero-zero. Now we have 0100. But it's still reversed. So we have to reverse it again. Now we reverse it again and we have 0010, which is two in binary. Now we have completed the routine and we can return to whatever asks just to compute these two values. [0:45:59] JG: And it's that times a million. A large set of those instructions comprise this engine that you've written per the WebAssembly spec. [0:46:07] DM: Right. The number we just gave has 4 bits. But a 64 bit number - I mean, it maybe sounds trivial to say this out loud. But a 64 bit number has 64 bits. And I don't know if anyone has done this, but on your keyboard, just type 64 characters, it's a lot of characters. Actually, it's like kind of overwhelming to me that when I first started working with them that like, "Wow, that's a huge number of characters just to store the value one." But yeah, that's how it works. [0:46:35] JG: Wow. That's quite technically deep. I don't want to go too deep here because you have released a video, not a time of recording, but a time of release, diving into all the stuff that you went through with this, what you just described here, all the tooling you wrote around it. I would really encourage people to ideally watch that video. But at the very least, see the announcement video that you posted, because it really is a fascinating piece of work, just to list all the features. But in our last remaining minutes in the interview, I want to take a further step back away from the technical side and talk about the context around it. You referenced releasing videos and being the founder of Michigan TypeScript before. And you've talked a lot about the technical side of helping developers. How does Michigan TypeScript in your mind help developers in the non-technical or the information sharing world? [0:47:20] DM: I was angry for many years because I was trying to write TypeScript libraries and do fancy things. And I felt like I was working on stuff that was kind of cutting edge. And there was like no resources for me. The TypeScript docs are explicitly written without that use case in mind. They do mention a few for a sentence for some very advanced features, but it's not the audience of the TypeScript docs. And then I love to watch videos and stuff. And there's no creators making videos for advanced TypeScript stuff. And I kept really, really wanting somebody to do that. And nobody would do it. I thought this is weird because TypeScript is sufficiently mature at this point. There's people writing TypeScript for - I mean, I'm one of them in a way. I've been writing TypeScript since 1.0, right? There's enough of this TypeScript code in existence now that I think there's a place for people who are doing advanced stuff to get some resources to help them to learn from other people how they do it, right? And I just really, really badly wanted that to exist, and no one would do it. So I did it. I didn't want to do it. If somebody listening would like to take it over, I'm very interested. I will keep doing it. I love doing it. It's fun for me. But it's not something that I - it wasn't in my bingo board, I guess, for my life to be doing this kind of stuff. And I don't consider myself a YouTuber. Michigan TypeScript has very, very few videos that are just me. I think there's only - it's just the Doom basically. Just the Doom videos and like one other video. We have other people that we're kind of interviewing and I play the interviewer to do that. And somebody needs to. But I view it more as like a collective personally. I think there's a lot of people who have helped out with it by nature of the fact that we have - I think in last year or a year and a half ago, we had like 60 people on the channel I counted in one year. It's a lot of people. Not me. 60 non-Dimitri people. I think that motivates me to continue. But I don't know. I found out actually, for anybody thinking of doing a similar thing in your own, it doesn't have to be TypeScript, but I think you have to go into it with the right reasons if you're going to do service the other end of the industry. That is to say not beginners. Because if you think of like a funnel, like a marketing funnel, there are far, far, far fewer people who really will sit down. Everyone says and thinks that they would sit down to watch a one-hour blow your mind technical deep dive. But the reality is almost no one will, including me, by the way. There's lots of stuff on my wish list that I would love to sit down and watch and learn about, but I just literally can't. In a way, I'm not a target audience either, I suppose you could say, because I don't have the time to watch some of the kind - we have many hour-long videos doing very advanced deep dives. But I like the idea that it exists. I like the idea that someone can learn that if they want to. And it's motivating for me. We have a video that I'm proud of on distributive conditionals. And I'm not going to explain what it is here, but it's a very advanced typeScript feature that has basically nothing - blog posts. Basically nothing written or done about it. But if you're a library author, I think you kind of need to be aware of what's going on and how this works. It's a thing that I've shown to people and they've said, "Wow, I knew that was something weird there. I hit that before, but I couldn't figure out what was going on. It just seemed weird. It seemed unpredictable." It's like, "No, it's not unpredictable." Everyone knows this about software. This software is not unpredictable. However, where would someone go to learn this? And so I'm very proud that we have a video about step-by-step teaching. It's only eight minutes long. So it's, I think, very consumable in that way, teaching how to make sense of these things. And yeah, I find that very motivating to have that up there. But I personally don't enjoy the spotlight. It's fun to talk about these things. But if I could go back, I think I would have first learned to operate a puppet. And maybe I would have done the VTuber thing, or I would have had like a puppet talking instead of my face, because I don't care to be personally known. I don't want a legacy in the TypeScript world or something like that. I just want this stuff to exist. It doesn't matter to me who makes it. [0:51:10] JG: Yeah, it is interesting. All the Michigan TypeScript Dimitri Mitropoulos branding online, there is no mention or no visualization of your face. The closest thing is Cookie Monster. This one avatar you use. [0:51:22] DM: Yeah. But what's coming next? What are you going to do now that Doom is out there? [0:51:29] DM: Nothing. Yeah. I think I'm just going to going to take a break. I don't think this is going to be something that I can ever do. Some people have asked me like, "Oh, what's your next project?" And it's like, "Yeah, it's not going to be anything like this." This is a lightning in a bottle situation. I think I happen to be in the right place at the right time. And that's really what this comes down to. I knew a bit about advanced type-level programming enough to make me think I could figure out the reason why it wouldn't be possible. And I didn't know enough about any of the other parts of this to ward me away. If I knew what I knew now, I would never try. T think my career is definitely downhill from here. I can't imagine any other way. I will say there's two projects that we're going to be working on next with Michigan TypeScript that are gonna be a bit different. One of them is with Dan Vanderkam. Dan has a book called Effective TypeScript. And the subtitle of the book is 83 Specific Ways to Improve Your TypeScript. And I saw that, and I pre-ordered the book and I was very excited. And I know Dan. And I think you do too. He's a wonderful, wonderful person. [0:52:24] JG: Lovely. [0:52:25] DM: So I was like, "Dan, this is -"I reached out to him and was like, "This is perfect. We got to make a video series on each of one 83 ways." We'll make like a short series. It's not going to be long-form, hour-long content. But he already did all the work of compiling all that stuff. And it's like perfect format to translate into videos where we can say, "Here's item number 55, item number 62." Dan and I are going to be making videos on that sometime. The next project that I'm going to be working on is actually sort of similar. Maybe people are going to get tired of Michigan TypeScript because these are both longer - 83 is a lot. And then also, there's this other one. Andrew Branch and I are - I'm not trying to make an announcement, but the plan is right now to make a video for each TS config option. I think this is something that advanced users need to understand really deeply. But there's a lot of stuff going on with the TS config and there's a lot of options. I don't know. Dozens and dozens. I don't think it's a hundred. But maybe it is. Maybe it's close by now. It feels like 100 some days. And so we're going to make a video. Andrew's on the TypeScript team. And he's a world expert. And one of the hardest parts of JavaScript and TypeScript, which is module resolution. And he's going to help, I think, a lot of people by - he's already done some such great work. He has long documents he's put together. But we're going to be doing some work on explaining what all of these things are in a format that I think you can reach out and access if you're facing it. If you get some error and you think it's about some particular TS config option, you'll have a place where you could just go watch a video that explains what that is in like two minutes or something, two or three minutes, that is going to be handy to just have on access. Yeah, I think that's going to be exciting. And I like content like that too because it doesn't require a lot of planning because the work has already been done by their book author or a TypeScript team in these two cases. That's what's up next. [0:54:16] JG: I would love to keep talking with you and dive more into all the fun parts of TypeScript, and Doom, and Michigan TypeScript. But unfortunately, we're about to run out of time. One last question area before that. In the video, do you have a split-second view of you playing musical instruments? Did you yourself record the Doom video music? [0:54:38] DM: I did, yes, but it's not the one that doesn't end up in the video. What's funny, maybe I'll release it sometime. All the music on Michigan TypeScript is open source, and that means you can go on our GitHub and find there's a music repo. And all the music we use until that video was - literally, every sound effect and everything was created just for Michigan TypeScript, because I'm very paranoid of copyright strikes and stuff and hosing the whole channel. I have friends. I have a friend that had thousands of videos and he was doing it for 10 years. And the channel got taken down because he did like a cover of an Eagle's song, like Hotel California or something like that. And yeah, they just shut down his channel, deleted every video, and his life's work is just destroyed. I'm very nervous about that. Anyway, I did create it and I did record it and make a little kind of like music video, and I thought I would fit that in. But you know how it goes in software projects. Scope has to get cut. And despite the fact that I've recorded, I think it's like 85% of the song. I mean, almost the whole song. And it sounds really good. I'm very happy with it. And I recorded all the instruments and did video. Recorded myself playing all the instruments and everything else. It just - time. It's like the extra 15% it would have taken. I really needed to just get the video released and I decided that I would cut the scope the moment I found out that Bethesda, the owner of that track. That track is made, it's from Doom Eternal. It's a Doom music. And Bethesda has a specific written policy that you can use that music in the context that I used in that video. I can't just publish the music with aesthetic art and then like as music, but I can use it in the context of some other video that has commentary and stuff, which obviously it does. And when I saw that, I thought, "Okay, well, if there's a copyright strike, I can just point to that license that I've been granted and everything will go away and it'll be okay." And I deleted from the video my homemade track. But that's how it goes, I guess, sometimes. And then the video was already there of me, because that's the joke. In the video I say, "I didn't do this because I have no other way to play Doom." And the joke is I'm literally physically playing the Doom music, you know? That's why it's there where it is. And yeah, it's a little kind of visual double entendre. Oh, well, maybe I'll put it out someday. I don't know why anyone would care, because the original is so awesome. But yeah, that's why it's there. [0:56:59] JG: Completely unrelated to TypeScript. You were in a metal band at some point. Is that where you learned to play all these different parts of the song? [0:57:05] DM: Yeah, I've been in many bands. I was in a Tom Petty cover band as well at one point. I don't even like Tom Petty, but it was a fun band to be in. I think doing other things and having other pursuits in life is a very important element to being proficient in a specific thing. I think that people who go deep in a particular area often, I think, get hamstrung eventually. You are going to be restricted at some point if you keep pushing. It's important to do other things. People say touch grass. Well, I think there's a lot you can do that doesn't involve grass. I think we hyper fixate on being outdoors. And some people are really great. Actually, Dan Vanderkam is a great example. Dan is a very established hiker. And he has like a hiking blog. I mean, he really goes for it. It's amazing to read his - see pictures of mountain tops that he's been on and stuff. I've nothing against that. I've done some hiking myself, and I love it. But I think that doing completely other things in life, having totally separate hobbies can create synergies that you just can't predict. And it's worth it to do other things. It will make you a better software engineer if you learn to cook, or if you learn to knit, or whatever. It doesn't have to be something - these are two - hiking, cooking, and knitting are prototypical hobbies. But he doesn't have to be hobbies. It can be volunteering at a nursing home near you, which I personally have grown - I also worked in a nursing home as a speech pathologist for six months. And those experiences that I got come to my mind still. It's been a decade or more, I guess. And it put a lot of perspective in my head that I think I use as a software engineer. I think it's very important to do those kind of things, do other stuff in your life. Yeah. [0:58:47] JG: Absolutely. Well, Dimitri, we're out of time, but this has been a wonderful interview. Thank you so much for coming on. If people want to learn more about you, Michigan TypeScript, any of the stuff you work on, where do you direct them on the internet? [0:58:58] DM: Thank you for asking. But I'm not really accessible on the internet, I think. I'm on the Michigan TypeScript Discord. I guess you can find me there. But I don't have any social media or any other things, never have. But if you're interested in Michigan TypeScript and you want to learn more about advanced type double programming and those kind of things, definitely, it's just Michigan TypeScript. Most places on Twitter. I think it's MI TypeScript. And it's easy to find, I hope. There's not a competitor in the SEO. If you just search Michigan TypeScript plus whatever place you want to find us, I think that discord.michigantypescript.com is an easy way to get to the Discord if you want to chat. And, oh, also SquiggleConf. We didn't talk about SquiggleConf, which is kind of funny. But I'm very passionate about DevTools like we talked about. And we have a conference. You can come to SquiggleConf. And the joke being, of course, that we're the people who make Squiggles, right? The people who make DevTools, often the result, the output of our DevTools is a Squiggle in somebody's editor or in their CI or something. Anyway, that's another cool way to connect. And it's been a very exciting experience doing that. I think a lot of people have enjoyed it. I've enjoyed it. Yeah, those are the main ways. [1:00:02] JG: Absolutely. Well, thank you again. For Software Engineering Daily, this has been Dimetri Mitropoulos and Josh Goldberg. Thanks for listening, everyone. Cheers. [1:00:11] DM: See you later. [END]