CppCast - Dart and Crafting Interpreters

Episode Date: September 16, 2021

Rob and Jason are joined by Bob Nystrom from Google. They first discuss git commands explained via cats and an analysis of how Visual Studio 2022 could use all your RAM. Then they talk to Bob about so...me of the programming languages he's created, his two books 'Crafting Interpreters' and 'Game Programming Patterns' and his work on the Dart programming language at Google. News Safer Usage of C++ in Chrome Git commands explained with cats Meeting Embedded 2021 How Visual Studio 2022 ate up to 100GB of RAM Links Crafting Interpreters Game Programming Patterns Dart Programming Language Flutter Robert Nystrom's Blog Vigil on GitHub Sponsors Use code JetBrainsForCppCast during checkout at JetBrains.com for a 25% discount

Transcript
Discussion (0)
Starting point is 00:00:00 Thank you. exclusively for cpp cast jetbrains is offering a 25 discount for purchasing or renewing a yearly individual license on the c++ tool of your choice c-line resharper c++ or app code use the coupon In this episode, we discuss C++ in Chrome and Visual Studio eating all of your RAM. Then we talk to Bob Nystrom from Google. Bob talks to us about Dart and creating his own languages. Welcome to episode 317 of CppCast, the first podcast for C++ developers by C++ developers. I'm your host, Rob Irving, joined by my co-host, Jason Turner. Jason, how are you doing today? I'm all right, Rob. How are you doing?
Starting point is 00:01:41 Doing okay. Starting to get back into the swing of things. Past Labor Day. Kids are in school. That's right. Normal people get holidays and vacations and let's be fair. I think vacations, but holidays don't mean the same thing to me being self-employed for the last 11 years. Sometimes I like email clients and be like, why didn't they respond to me today? Oh, cause it was Labor Day. Oh, right. Yeah, yeah. You should take some time for yourself, though. Don't work every day.
Starting point is 00:02:12 Well, no, I mean, you know, let's be fair. I'm not working 12 hours a day every day or anything like that. But I just don't notice necessarily. Right. And sometimes I make a point of working on holidays because then I know that I'm not going to get emails from people. Yeah, that is always nice. All right. Well, at the top of every episode, I like to read a piece of feedback.
Starting point is 00:02:32 We got this comment on Reddit from the episode we did a couple of weeks ago with Justin Miners talking about that course from Alexander Stepanov. He wrote, this was a really great episode. One can never have enough Stepanov. However, Jason said something in the beginning, which I think isn't quite right. While Valgrind as an emulator can tell you exactly how many instructions your code uses, it can't do a good job of telling you how many cycles, which is often more important. Moreover, the Linux perf tools that use the hardware performance monitoring counters are not all sampled, and some give you exact hardware measured counters for instructions
Starting point is 00:03:05 retired, cycles, branches predicted, and all kinds of obscure low-level detail that is oh so much fun to geek out about. So I would clarify, I don't recall exactly what I said in that episode. But I do know that you cannot get a good cycle count from Valgrind. It does give you an exact instruction
Starting point is 00:03:22 count, which is usually good. But yeah, I actually do recommend that you do a combination of Valgrind to get an exact instruction count and perf tools to then give you instructions retired per cycle and combine those two metrics together, which can give you a highly stable representation of the performance of your application, where if you do just performance counters or just timing, those things are really volatile. And then you can watch, you know, an hour presentation that Bryce did at CVPCon a few years ago about how to statistically analyze
Starting point is 00:03:54 all that data, or instead combine Valgrind with perf tools and get something that's very stable and not have to do a statistical analysis of your timing data. Definitely good recommendation. Okay'd love to hear your thoughts about the show you can always reach out to us on facebook twitter or emails at feedback at cppcast.com and don't forget to leave us a review on itunes or subscribe on youtube joining us today is bob nystrom bob is a software engineer at google working on the dart programming language before falling in love with programming languages and compilers he was a game developer ui programmer, pixel artist, and computer animator. He's the author of Crafting Interpreters and Game Programming Patterns, a college dropout, and a fairly decent cook. Bob, welcome to the show. Howdy. Thanks for having me. Bob, I'd like
Starting point is 00:04:37 to ask you about your pixel art, but instead I think I'm going to have to ask you what you like. Oh, come on. Let's talk about pixel art okay sure why not why how did you get how did you get interested in pixel art uh oh man uh uh you know i mean i so i'm in my 40s now and i started using computers at the time when all art on computers was pixel art you know i wanted you know when i was a kid i wanted to make nintendo games and the first time i got access to an apple 2gs which is the first color computer I got access to. First thing I wanted to do was like, I want to make cool pixels. And then, yeah, I don't kept doing that. There was a summer in college where basically that was my job. I was a freelance
Starting point is 00:05:14 pixel artist. So I would pick up contract work for people that needed, you know, buttons and stuff like that on the webpage and, and do that. Wow. That's cool. Anything that, uh, I don't know, anything that ended up in a game that we would recognize or anything like. Anything that, uh, I don't know, anything that ended up in a game that we would recognize or anything like that? No, uh, I don't think so. Let me think about that. No, probably not. You know, by the time I was a professional game developer, you know, when I was working at EA, um, I was just a software engineer, so I wasn't doing any art then. No, no chance that you created that little under construction guy that we all knew from the early internet. So there was, man, I can't even remember the name of it now.
Starting point is 00:05:50 There was a company that would do custom cursors that you could put on your web page. You know, you go to the web page, your cursor turns to some terrifically annoying, horrible thing. Yeah, they ended up getting bought out several times. But back in the late 90s, one of my biggest contracts was doing custom cursors for that so there's a good chance that if you went to a really annoying web page in like 1998 and you're like i really hate this cursor that yeah that was that was me okay great great i will i will blame you for that yeah from now on all accepted wonderful obviously a lot to talk about but you did just briefly mention that you worked at e for a while. What games did you work on while you were there? A bunch. So I was at EA for eight years.
Starting point is 00:06:29 I worked on Madden PC, 2002, I think. Sounds right. A couple of other versions of Madden for the consoles. Worked on Superman Returns the Video Game, which was the video game adaptation tied to the brandon routh superman movie that was uh not very good and the game was correspondingly not very good um you need good source material for movie uh it was not a good game for many reasons uh up to and including the quality of the film um and then uh worked on this game called Professor Henry Hatsworth and the Puzzling Adventure, which was a DS game. And that was a super fun project.
Starting point is 00:07:11 It was a fantastic game. But most of the time I was there, I was like a tools programmer. So I was working on UI libraries and internal tools and stuff like that. So not stuff that was like directly tied to a single game, but shared code or tools that people were using to author games. It sounds way more fun to me than being like under the spotlight. Pressure. Yeah, pressure and everything of the actual game development.
Starting point is 00:07:37 Yeah, 100%. Yeah, one of the reasons I kind of moved into that area is just having a better schedule. You know, being tied to the game team schedule is brutal. When I worked on Superman Returns, I was the tools lead for that game. So I was directly tied to the game schedule. And we crunched for nine months, so nine months of 60 plus hours a week. And that sucks. That's not a thing that anyone should do ever for a game that shitty. Frankly.
Starting point is 00:08:11 All right. Well, Bob, we got a couple of news articles to discuss. Uh, feel free to comment on these and we'll start talking more about, uh, the other work you've done.
Starting point is 00:08:19 Okay. I'll do my best. All right. So this first one is a post, uh, from Google on safer usage of C++ in Chrome. And I was actually wondering if you're familiar with some of these, you know, guidelines, Bob, that are happening within the Google team.
Starting point is 00:08:39 I went through that. I'm, you know, only passingly familiar with any of that stuff. And I'm also not sure of the bits and pieces that sound familiar what I'm allowed you know, only passingly familiar with any of that stuff. And I'm also not sure of the bits and pieces that sound familiar, what I'm allowed to comment on. Okay. You know, so I have things that said this is an internal document only in the links. Yeah. You know, so I do work at Google. And I work on an open source project, which is fantastic, which means like 99% of the stuff that I do, I can just talk about freely, which is one of the, one of the reasons I really like working on it. Um, but you know, stuff like that, you know, kind of tied to the Chrome team and the larger Google organization.
Starting point is 00:09:12 I'm always like, I don't know which of these is sort of crossing the envelope that I'm allowed to talk to. Um, but I don't, uh, I don't write any C plus plus code at Google. So I'm also, uh, you know, I have a professional interest in kind of the evolution of the language. And I have, you know, a lot of historical interest and kind of experience with C++. But I'm not tied into like, you know, what the daily experience of using it is at Google. I've written this much C++ for Google, I think, which is non-zero, but very small. All right. Jason, do you want to tell us about this next article you put in with git per commands explained with cats? Oh, yeah.
Starting point is 00:09:51 Why not? It looks like fun. And this thing's actually like three years old, and we haven't talked about it yet for almost four years old. But it's just common git commands that are cute cat pictures. Like it's, what else do you say right like get push and it shows like little icons of cats being pushed to servers and remotes and stuff and it's a very nice visual explanation it is very cute i like get merged there's the tabby cat merged with the cat that has a bow tie and now it's a tabby wearing a bow tie like it makes sense that visual could have gone
Starting point is 00:10:25 so much worse it could have been like jeff goldblum in the fly right like you can't eight legged cat with right that's a merge conflict i guess i guess that's what that is yeah definitely uh and the next thing we have is announcing meeting embedded 2021 obviously this is coming from uh jens veller who also works on Meeting C++. And this is going to be November 4th, single-day, online-only conference. But the tickets
Starting point is 00:10:53 are available. It's €99 for early bird. How long are these early bird tickets available? I don't think it says, does it? More details soon. That's what it says. More details soon. Well, yeah, if you're interested in embedded programming, certainly check out the Meeting Embedded conference. Yeah.
Starting point is 00:11:11 No, I don't see dates listed for... I just went to the ticket shop to buy it. It doesn't say when the early bird expires. Right. Okay. And then the last thing we have is a post from PBS Studio's blog, and this is how visual studio 2022 ate up 100 gigabytes of memory and what xml bombs had to do with it uh so yeah this is pretty impressive
Starting point is 00:11:33 i'm really looking forward to visual studio 2022 myself and you know one of the big changes with it are going to be 64 bit means you can use more than 4 gigabytes of RAM, but we certainly don't want Visual Studio eating over 100 gigabytes of RAM just because of an XML file. I don't think I've heard of these XML bombs before. This is completely new to me. Yeah, they're done using these XML entities, and apparently you can just keep nesting
Starting point is 00:12:03 and repeating them, and it can just cause, yeah, XML parser to just continue trying to expand this ever expanding node of entities and can be pretty scary. Was this something you were familiar with, Bob? I don't know if I was familiar with XML entities being able to expand, but, you know, this is definitely a thing that comes up. I've worked on tools for a long time. I work on language tools now,
Starting point is 00:12:29 and you do kind of have to think about, is this a construct that users can nest and combine arbitrarily deeply? And if so, do we get exponential memory usage and try to avoid that, basically? But it does come up. It's something a lot about, uh, implementing language tools. So I work on the Dart team at Google now. Uh, and, uh, yeah, it's a real thing, right? It's a real thing. That's like part of language design, you know, so Dart has, uh, constants that has compile time expressions.
Starting point is 00:13:00 They're, they're super limited. Um, part of the reason that they are limited is that they are designed such that you can't get into this situation, right, where the size of a constant, the amount of memory that it will put in the final executable is designed at the language level to be, I believe, only ever a constant multiple of the size of the source code, right? So you can't create a constant bomb like this by nesting them deeply and then getting this sort of combinatorial explosion. I'm not 100% certain that we've accomplished that, but I'm pretty certain we have. And it's designed that way deliberately to do that because it's a real thing, right? Interesting. Never thought about that as a safety check in the language, because I don't know of any C compilers, C++ compilers, that is, that will stop you from doing that. They give you, in fact, flags to turn up all the limits if you really want to. Yeah. Yeah, that's kind of the tricky thing, right? Like when you're working on a language and working on the tools is, you know, to what degree do you bake these limits into the language
Starting point is 00:14:00 itself versus saying that, well, the language will let you do these things arbitrarily deeply, but some tools may not support it. You know, so for example, like, expression nesting is a simple thing, right? Like, you've got your language, it has expression syntax, right? Like, it has a grammar. And in theory, you can do A plus B plus C plus D plus forever, right? And the language grammar says it's okay. But some parsers may blow up on that, right? They may have a limited amount of like you know if they're doing a recursive descent parser they may blow the stack in the parser itself right and do you how do you handle that right like you could just you know you can put an arbitrary limitation into the tool which is what most do and that's a valid solution but that can also lead to now
Starting point is 00:14:40 you've got incompatibility between tools right you have an expression that parses in one tool but not in another, and users are like, okay, now this is a problem. It's weird. Scale limits like that get strange, and it is a real thing that you kind of run into. We have language tests that are just like, make sure it can parse really deep expressions
Starting point is 00:14:56 so that our various parsers, so that we can validate that they handle it and they don't blow up. I was just going to comment real quickly back to the XML thing with Visual Studio. It does mention that this is referred to as DTD processing that enables these entities to be processed. And it looks like the default is to not process them. So whatever's going on in Visual Studio, obviously they must have enabled it for some reason. You know someone got burned by this before they added that flag, right? Sure. for some reason, but I am. Yeah, you know, someone got burned by this before they added that flag, right? Like, sure.
Starting point is 00:15:29 Well, it seems the conclusion in the article was that it was added, that it's enabled in Visual Studio so that mouse over tips work so that you can mouse over and see what the expansion is supposed to be. That's a big tool tip to fit 100 gigs of textual data in it. Okay, well, Bob bob let's start talking more about uh what you work on so you already just mentioned that you work on the dart programming language but i wanted to maybe
Starting point is 00:15:55 start off with how you got into creating programming languages because in addition to working on dart you've made two of your own right uh i I have a wide variety of hobby languages, almost all of which have zero users, which is probably the median number of users for any given programming language in the world. My career path doesn't make any sense at all. I dropped out of college. I never took a programming language class before I dropped out, so I don't have any real like academic or formal backing in this stuff. Um, but when my, when my oldest daughter was born, uh, this is 12 years ago now. Um, and I was on paternity leave. Uh, my wife and I ended up on a schedule where it was basically nocturnal. So I would do the bottle feedings in the middle of the night. Um, and I had a bunch of downtime.
Starting point is 00:16:45 And I was like, okay, well, you know, I need a little project to work on. And I've always been kind of interested in programming languages. So I was like, I'll try to make a little language. And it was super fun. It turned out it was a thing that I was just really, really fascinated by. So I got into it as a hobbyist. And, you know, I was sinking, you know know lots and lots of my free time into it and then a couple years later somehow managed to finagle my way onto a team at google doing that
Starting point is 00:17:11 as my job joan tell us about some of these hobby languages you made uh sure so the my my highest profile hobby language is this language called vigiligil, which is a complete joke language where I don't remember the name of it. But basically, several years ago, this person had this idea of doing, do you know what video game jams are? You know what game jams are? Yeah, yeah. So, you know, you have this time box thing of like a bunch of participants make a game within some constraint. And it's a way to sort of get over the hump of like finishing a full game is super hard but if you just time box it and you can make a tiny game then you can kind of get some practice finishing stuff right um and
Starting point is 00:17:54 this person had this idea to do it for programming language like yeah we're gonna do a programming language jam or it's like you got like 24 hours to like design and implement a language according to some theme what was this You said a few years ago? Yeah. Well, this is, oh man, Vigil's probably more than, it's probably like six years ago or something. Interesting. I don't know.
Starting point is 00:18:12 Okay. In the pandemic times, time has no meaning to me. So this person had this idea of like, yeah, we'll do a programming language jam. I was like, that is 100% up my alley. Right. So I was like, all right. And then the theme that came out with for the first one was safety. And I was like, oh, that's really cool, right?
Starting point is 00:18:30 Like there's a bunch of like interesting, you know, ideas you could do there with like ownership types or something like that. And I was thinking about this on my drive home from work. And I was like, well, what's the weirdest idea I could come up with? And I was like, well, the best language is one that doesn't just catch unsafe code like that's you know you think of it as sort of like a uh you know level one of tooling is it tells you when you made a mistake level two of tooling is when it fixes the mistake for you right so it's the difference between having a linter that tells you that your code is formatted wrong versus having a formatter that just formats it for you. Right. And I was like, okay, well, most safety features and languages, uh, you know,
Starting point is 00:19:10 they just tell you like, oh, there could be a use after free here, or, you know, this has gone out of scope, whatever. I was like, the next level should be like, it should just fix the code. And I was like, well, what's the, what's the right fix? And it's like, well, if it, if the code contains anything that's unsafe, it's obviously bad code should delete it. So, so what vigil does is, uh, basically you can put assertions in it. It's a, it's a variant of Python and it, the implementation of vigil is literally just some red jacks that applies to your Python program. And then a wrapper. Um, what it does is if a runtime exception is, so you can have these assertions,
Starting point is 00:19:46 you can put in your Python code. And if one of those assertions fails, it finds the surrounding function and deletes it from the source code on disk. On disk. It's bad code, get rid of it. So I implemented this using like, I don't know, like a hundred lines of like garbage Python
Starting point is 00:20:03 and some regex. And then I wrote a readme that explains how the language works. And the readme is written in this like very sort of like totalitarian style. Uh, and I was like, this is awesome. It's like the most fun I've ever had. And I was like, all right, here's my submission. Um, I don't think anyone else submitted anything to this programming language jam. And it turns out that programming language jams are a terrible idea because who wants to implement a language in a day? I have to, if you don't mind, interrupt real quick because my cousin just ran a programming language jam three months ago and he got a huge response to it.
Starting point is 00:20:36 They got like 30 submissions of people that actually implemented programming languages in a weekend. That's amazing. His Discord is still active like active right i want to know more about this what what's it called uh i think it's just called lang jam oh i did yeah i did see that go by i'm not at a point in my life where i have the kind of free time for that anymore unfortunately um that's awesome yeah yeah so lang jam is the g the GitHub repository to get. Is he doing it again?
Starting point is 00:21:08 The planning to there. I don't think there's been an announced date for the next one yet. I was telling him you need to do that, like announce it and make sure everyone knows what the plan is. But yeah, I'll pick him again. Was there a theme for the first one? Yes, it was first class comments. I love it. That's awesome interesting so there are people who did really creative things with that uh yeah that's super cool one of them was a i'm sorry now i'm going to completely derail this but this is great i'm on board it was a uh train simulation language So like there's just trains moving around on the screen and they have switches and whatever.
Starting point is 00:21:47 And any comments that were in the code were things that passengers said. But the passengers who were in first class, anything that they said actually affected the train, like change to the color of the car or whatever. That's great. Right? Love it. It's pretty good. All right. Well, so we talked a little bit about your getting into programming languages.
Starting point is 00:22:16 You want to tell us a little bit more about Dart and maybe give us an overview of language? I don't think we've really ever discussed Dart before. Sure. So, yeah, I mean, I can spend a lot of time talking about dart um uh so what is the the elevator pitch for it is that it's a multi-platform client-side ui application language uh and there's a couple of different pieces there um so it's a language designed it's a general purpose programming language. You can write all sorts of stuff in Dart, obviously. But the sort of main focus is writing client side application code, you know, UI code, um, because you don't control the hardware that the code is running on, right? It's, it's running on some user's device, a phone in their hands or something, you know, so a language like Ruby or Python running on a server,
Starting point is 00:23:13 if the language is too slow, you just spin up more servers and there's a cost, but it's a cost that you can just control, right? Like you can just choose to sink more into it. Whereas if it's running on a device, you don't own, uh, execution performance matters a lot. Um, and also if it's running on a device in particular, a mobile device, that also means that code size matters a lot. You know, you don't want to compile to this 500 megabyte monstrosity. Um, it means that startup time matters. So it's not just, uh, you know, aggregate throughput over time, like, uh, you know, the JVM, you know, your Java code running on a server, maybe it's kind of slow when it starts up, but as the JIT warms up, it gets faster and that's okay. That's less true for a client side language. As soon as the
Starting point is 00:23:52 application starts up, people expect it to be snappy. And it means that the performance matters at a fine grain level, right? So it's not just enough to have high throughput. You need to have low latency performance, right? You need to not drop frames. So all that stuff kind of, so at the technical performance level, that puts some constraints on the language. And then because it's a language for application programming and UI programming, there's also productivity constraints on it, so I don't know if you guys have ever done UI programming, ever done kind of client app stuff. Yeah. So there's a lot of just like iterating on the user experience, right? Like moving buttons around, changing colors, and that needs to be fast, right? Because like a whole lot of just improving the quality of the app is just tweaking
Starting point is 00:24:38 stuff. So you need to have a fast iteration loop. And the language overall needs to be productive, right? Like if it takes you two weeks to add a new, a new form or a new button, that's, that's not feasible. The timescale that people doing application development work on is, is much shorter than that. So, you know, so at one level we're pushed to make a language that's low level, so it can be fast and another, but we're also pushed to make it high level so that it can be productive. And Dart kind of is, tries to sort of like, you know, find the middle ground there. Um, I know you said general purpose, but it sounds like is, is one of the main use cases like mobile app development. Yeah. So the, the main thing people
Starting point is 00:25:14 are using Dart with now is, um, Google has a application framework called Flutter that is growing really rapidly. Um, and it's, you can think of Flutter as, uh, it's in the same vein as like Cordova or, uh, react native where it's a, it's an application UI framework that lets you target multiple mobile platforms. So Android iOS, um, for Flutter, we're also working on, uh, web support and desktop support too. Um, so it gives you a single code base that lets you target more than one of those. And Flutter is the main thing, the main place that people are using Dart these days. There's other frameworks and other ways to use it,
Starting point is 00:25:53 but Flutter is kind of the Ruby on Rails for Dart, right? So it is a compiled programming language, you said, right? It is. So looking at the language itself, it's object-oriented, deeply object oriented. You know, every object is an instance of a class. You know, we have classes, inheritance, all that good stuff. It's statically typed. It has a pretty nice modern sound static type system, generics, stuff like that, generic methods. We have null safety now. So we have, you know, the type system will help you avoid null reference errors.
Starting point is 00:26:25 Um, it also has a bunch of functional features. So we have first-class functions, closures, higher order functions, all that good stuff. Um, it doesn't do the thing that Java and C sharp do where all code has to be stuffed inside some class. You can just make top level functions. So it's not, uh, it's not dogmatic about being object-oriented. And then at the back end, the implementation, we have a virtual machine and a JIT. So you can run it kind of like a scripting language where it will just immediately start up and run from source as quickly as possible.
Starting point is 00:26:55 And when you're iterating on it, when you're iterating on your Flutter application, we have this thing called hot reload where you can change code and literally within milliseconds see the change in the running application right so we will jit it on the fly and then reload it into the running application without resetting any of your state so we have kind of like that scripting language uh experience
Starting point is 00:27:15 but then we also have a uh an ahead of time full native code compiler so we will take your dark code and compile it all the way down to you know x, x86 or ARM machine code. Is it a LLPM backend or? Nope. We, uh, so we have on the Dart team, we have a surplus of compiler expertise. Uh, so we have a full, you know, so the, the Dart project, um, historically it's spun out of the, the handful of the people that created V8, which is the JavaScript VM in Chrome. These are very old school compiler VM hackers, and they were sort of frustrated by how difficult it is to implement JavaScript efficiently,
Starting point is 00:27:59 and then how frustrating it is to write JavaScript code at scale. So Dart was sort of their idea of like, well, what if we designed a language that was both easier to implement a compiler for and better for programming in the large? So we've always had just a lot of compiler expertise and a lot of VM and compiler folks on the team, which is a real advantage for us. We have super mature implementations of a JIT, a native code compiler and a web compiler. So we can also compile your dark code to a very efficient, compact JavaScript. And we have a super mature compiler for that. We're one of the few language teams that has both a mature native code compiler and a mature web compiler. There's a lot of, a lot of other languages that have a very mature one of those
Starting point is 00:28:47 and a getting their other one, but we've invested eight years at this point in both of them. Wow. Just going back to the mobile app stuff for a moment, I know one of the issues with making a mobile app in a general framework like this or React is making sure the UI looks, you know,
Starting point is 00:29:06 proper on Android versus iOS. Is that, that is the, that's the fundamental problem, right? Like I've been, uh, I've been doing like UI programming and tool stuff in that area since,
Starting point is 00:29:17 uh, I think close to, since the nineties, like 20 years. And, and that is, that, that is like the perennial issue,
Starting point is 00:29:24 right? Like you can have a single code base that targets multiple OSs. You know, it used to be Mac and windows. And, and that is that, that is like the perennial issue, right? Like you can have a single code base that targets multiple OSs, you know, it used to be Mac and windows. Um, but it's very difficult to do that without getting a user experience that is the lowest common denominator of the two OSs. Right. Um, and where it's really difficult to get out of the uncanny Valley where the application kind of looks native, but like everything just feels weird. It's like, oh, the shading is a little off and it's like the scrolling to, you know, and it's really frustrating for users, right? Because users have an almost tactile level relationship with the user experience. So when it's off there,
Starting point is 00:30:01 they experience it very strongly. It's like this unpleasant friction. And it's, I mean, it's literally true with modern touch mobile devices where you are literally dragging your finger. And if it, if it scrolls differently, it feels like the physical device is wrong, right? That's always been a super hard problem. It's still a hard problem. It's a little less hard these days because one of the interesting things about the web and mobile application sort of styles is there's less of a stock operating system look and feel for all applications on that platform, right? Especially with the web, we've trained users that each application kind of just
Starting point is 00:30:38 starts from scratch, right? It picks its own color scheme, its own look for buttons, its own feel in a lot of ways. So users are a lot more accommodating of variation in UI style, and that helps. And then with Flutter, the goal is to... So Flutter does render all of its UI from scratch. You can think of Flutter as almost like a mini browser where the core engine is written in C++, and it has its own, you know, all the way down to the pixels renderer based on Skia. So it's kind of a full stack replacement. And they work really, really hard for the parts of the user experience that do match the platform to keep up with it and to have a high fidelity experience. So when you scroll
Starting point is 00:31:22 on iOS, it should feel like an iOS scrolling. And when you scroll the same thing on Android, it should feel like native Android scrolling. And that's hard. It's just a, you know, it's not like a conceptually hard, it's just a big engineering problem, right? Like you just have to keep chasing both OSs and you just sink a lot of time into it. And one of the cool things about Flutter is, you know, Google is investing a lot in it. And I think they've just sunk the time into like, get closer to that than most other, you know, multi platform frameworks have been able to. cross-platform IDE for C and C++ by JetBrains. It understands all the tricky parts of modern C++ and integrates with essential tools from the C++ ecosystem, like CMake, Clang tools, unit testing frameworks, sanitizers, profilers, Doxygen, and many others. CLion runs its code analysis to detect unused and unreachable code, dangling pointers,
Starting point is 00:32:20 missing typecasts, no matching function overloads, and many other issues. They are detected instantly as you type and can be fixed with a touch of a button while the IDE correctly handles the changes throughout the project. No matter what you're involved in, embedded development, CUDA, or Qt, you'll find specialized support for it. You can run debug your apps locally, remotely, or on a microcontroller, as well as benefit from the collaborative development service download the trial version and learn more at jb.gg slash cppcast dash c line use the coupon code jet brains for cppcast during checkout for a 25 discount off the price of a yearly individual license so you did just mention uh how parts of flutter and dart are implemented in C++. So maybe we can talk more about that.
Starting point is 00:33:06 I'm also interested to know, does Dart have any sort of interop with C and C++? It does. Yeah. So the virtual machine and the runtime, which is kind of a subset of the VM, are all C++, right? Like every language implementation in the world, 90% of them are written in either C or C++, right? Like every, every language implementation in the world, 90% of them are written in either C or C++. And in particular, the runtime, the, you know, the core facilities that are running application builds on top of, you know, things like garbage collector, object representation, you know, dispatch logic, that kind of stuff that's almost always
Starting point is 00:33:41 written in C and C++. So, you. So V8 is written in C++. The JavaScript engines in Safari and Firefox, that's all C++. The JVM is written in C++. And the Dart VM and its runtime are written in C++. Most of our other tools and compilers are written in Dart. We try to self-host as much as we can. But the core stuff is all C++ because it gives you,
Starting point is 00:34:05 if you're writing a runtime and you're doing things like, to self-host as much as we can. But the core stuff is all C++ because it gives you, you know, if you're writing a runtime and you're doing things like, you know, okay, well, how is a Dart object represented in memory? There's just a metric ton of extremely low-level optimizations you want to do for that, right? So like, you know, doing things like pointer tagging where we say, okay, you know, this word is a pointer, but if the first two bits are one, then we know that that's actually storing an immediate integer at that location instead of storing a pointer. And all of that kind of stuff is really hard to do in a managed language, right? And if you're implementing a garbage collector, like literally a garbage collector, it's, it's not impossible, but it's difficult to do that on top of a, you know, a managed language.
Starting point is 00:34:43 I'm just imagining implementing a garbage collector from scratch on top of a managed language. I'm just imagining implementing a garbage collector from scratch on top of it in Java. Like it just sends... It's weird to think about. There have been JVMs written in Java. And years and years ago, when Smalltalk was a thing, and I don't know if you guys know anything
Starting point is 00:35:01 about Smalltalk, the Smalltalk programming language. I know something about it. Predecessor to Objective-C, It is the, yeah, it is the progenitor of objective C. Uh, objective C is like, uh, this Frankenstein monster of small talk and C, which is the, the unlikeliest combination of two languages. Uh, it's like, I don't know, APL and Lisp smack together or something. Um, so there's a ton of small talk was kind of in a lot of ways, the first dynamically typed object oriented language. And it was created in a time where machines were super slow. So to get to a point that it was usable at all, there was a lot of like foundational research on
Starting point is 00:35:37 how to implement dynamically typed object oriented languages efficiently that came out of the small talk community. And all of that affects the entire programming language world today. Like if you look at a JavaScript VM, like what fraction of the world's code is written in JavaScript, right? If you look at a JavaScript VM, like half of the optimizations in there came out of the Smalltalk community. So, and I was going to say, so there have been Smalltalk VMs written in Smalltalk. And I don't know i
Starting point is 00:36:05 like to think of myself as a pretty smart person but that stuff is like mind-bending to me so you're going down the road of interoperability as well i believe we did oh right yes yes you asked about interop uh we do uh so the there's a couple of different pieces to that. So one of them is the Dart virtual machine is, it is a C++ library, right? So we have a command line executable wrapper around it. So if you want to write a command line app in Dart and run it in the VM, that's the thing you can do. You can think of it as sort of like Node.js for Dart, right? Where it gives you a command line shell and a bunch of like file libraries and stuff like that. But that's all wrapped around this core Dart virtual machine that's written in C++, which is just a reusable library.
Starting point is 00:36:50 So the Flutter framework is more like, it's kind of bigger than most of what you think of as a framework. So the Flutter framework is a complete application stack. And the core Flutter engine is written in C++ and it embeds that dart vm in it right um but that vm is open source it's a thing that you can use yourself so if you wanted to you know imagine you're writing some new application uh some new large application and you wanted it to be scriptable by users you could embed the dart vm in that if you wanted to and then support dart as a scripting language and there's a you know there's an api for doing that
Starting point is 00:37:23 um that's not the most common way to interface Dart with a native language, but it's cool that that's a thing that you can do. Right. And then more recently we've been working on a new FFI layer where if you want to kind of invert things where your application is written in Dart, but you want to call out to C code and C++ code efficiently. Over the past... Fast function interface? Fast function, foreign function interface. Foreign function interface, sorry, okay. Yes, good.
Starting point is 00:37:52 Thank you for reminding me to expand random acronyms that permeate my life. I've used libffi, but only very briefly, like the GNU one or whatever, anyhow. Yeah, every language kind of has its own name for this stuff, right? So in Java, it's JNI, right? Java Native Interface. I think, I don't know, I could, yeah, I think FFI is a somewhat generic term.
Starting point is 00:38:16 I think it is somewhat generic, I agree. But we have, we've been working on an FFI system the past year or two in Dart so that it's easier to call directly into C code and C++ code from Dart with a minimum of overhead. That way, you know, imagine you're writing a Flutter application and you want to, this is kind of the driving use case for us. You want to call into some native OS specific functionality, right? Like you want to use some, I don't know, VR capability that iOS comes out or some new thing that Android comes out with and that is only exposed as a native API, we're working on an FFI for Dart that lets you do that.
Starting point is 00:38:51 And that kind of stuff is tricky, right? Because languages each have their own semantics and sending data between them efficiently is really this moment where the rubber meets the road there. And it's very hard to trade off the reality that their representations are different with wanting to minimize the translation for performance, right? So you want to send a Dart string to some C code, and it's like, okay, well, does the C code expect UTF-8 or UTF-16? Is it null terminated or not? And it's like, to a Dart programmer, those are all mostly abstractions, right? But once you start talking to another language, those differences become real, and they affect
Starting point is 00:39:31 performance, right? What is the actual interface that you're working on? What does it look like? Can I include a C header file and then call a function from it? Or do I need to explicitly say, call the function from this library, call this, like, I'm thinking about Visual Basic BB6 for some reason at the moment, how you would do it from BB6. need to explicitly say call the function from this library called this like i'm thinking about visual basic bb6 for some reason at the time how you would do it from bb6 i'm not the best person to ask because i don't work on it directly i'm sort of passingly familiar with it um i don't
Starting point is 00:39:57 know i believe there's a an imperative api to load effectively a dll or to load the symbols. And then I think what you mainly do is, so Dart has metadata annotations, which are, I don't know if you're familiar with like annotations in Java, little at syntax or attributes in C sharp, the little square bracket syntax. But there's some kind of like metadata that you can decorate code with. And for Dart, the way Ffi works is you have some dart code a dart interface or a dart function type um and then you put a few metadata annotations on that to say like well here's what this what these actual types are in c and then what and then the the dart implementation sort of synthesizes a translation layer for you so then in in your Dart code, you can call into this interface and under the hood,
Starting point is 00:40:47 it will map it to the, to the correct C function and map the parameters to the right types and kind of do what it needs to do to, to Marshall stuff in and out. I'm sure someone will correct me, but I think that's not too far off from how rusts interoperability with C works. Yeah. I think most languages are kind of generally trending in this direction of, you know, users prefer to write, they prefer to write code in that language,
Starting point is 00:41:12 right? Like if they're a Dart programmer, even though they're calling C code, they want to, their headspace is Dart, right? So languages are going in the direction of trying to automatically synthesize an interface in that host language so that most of the machinery, the low-level machinery is kind of hidden from them. It seems to be what users prefer. It's hard. Anytime you automate stuff like that, users give up a little bit of performance control.
Starting point is 00:41:38 And generally, at the point that you are interfacing with C and C++ is also the point where performance really matters a lot. So designing that well is tricky so you said you've been working on dart for about eight years are any like specific features you've worked on recently that would be interesting to talk about uh so the big thing i don't know if there's features that i personally worked on mainly that are super interesting to talk about unless you really want to do a deep dive on language nerd stuff, which I am always up for. The big thing that the entire language team
Starting point is 00:42:09 and the entire Dart team has been pushing through over the past couple of years is this thing called null safety. So we changed the type system of the language in order to be able to make a distinction between types that contain null and types that can't contain null so that we can make null reference errors. We can let the static type system catch null reference
Starting point is 00:42:28 errors. This is, you know, definitely relevant for the C++ community, right? So like, you know, we mentioned earlier that list of safety features that Chrome is talking about, you know, investigating trying to do. And a lot of that is null pointer access, right? Or use after free, which is kind of another flavor of that, right? Where you have a pointer that you shouldn null pointer access, right? Or use after free, which is kind of another flavor of that, right? Where you have a pointer that you shouldn't be touching, right? And, you know, so the main thing we've been doing the past couple of years
Starting point is 00:42:53 is Dart's original static type system worked like the type system for most garbage collected static languages where, you know, any reference type can implicitly contain null, you know? So C sharp and Java work the same way. I wish it hadn't initially been designed that way, but it was.
Starting point is 00:43:14 Finally, in the past couple of years, we decided to do the work to fix that and to migrate to a static type system where a reference that can be null is a different static type from a reference that can't be null. We don't let you call methods on a reference that can be null is a different static type from a reference that can't be null. And we don't let you call methods on a reference type that is nullable. And then there's a bunch of language features that we have to add to make the user experience for that tolerable. Wait, I'm sorry. You just said you can't call methods on a type that can
Starting point is 00:43:41 be nullable. So then do you have to like call like a.get or like a checkout kind of lock or something like that? Right, so this is the fun stuff, right? And this is why it's hard to do this stuff in a language like C, right? So for Dart, in order to make this, you know, so there's the type system changes, right? It's like, okay, yeah, we're gonna have these different types, right?
Starting point is 00:44:01 We're gonna have nullable types and non-nullable types. That's a thing you can do in the static type system. And then one of the things the static type system does is it decides which operations are compiler errors or type errors, right? And then we can just say, yeah, it's a type error to call a method on a nullable type. Done, right? You know, ship it. But what you get is a language that's like impossible to use, right? Because it turns out that the absence of data is a useful thing to model a lot of time, right? So you do have regions of the program where users are deliberately using nullable types. But data needs to move across that boundary, they need to be able to get from
Starting point is 00:44:37 the nullable part of the world into the non nullable world where they can do stuff with it, call methods on it. And if you just change the static type system and you just add a bunch of compilers to the language, what you get is a language that can technically model what you want, but it's just impossible to use, right? Like the user experience is a net negative. So what you ideally end up doing is you make the static type system more sophisticated, but you also add other language features to make it a usable experience. And that's something that, you know, we can do in Dart because we own the whole stack, we own the language and the static type checker. But it's a lot harder for a language like C++,
Starting point is 00:45:13 where you're trying to sort of, you know, maybe bolt on a separate static analysis, but you can't, you don't have the luxury of adding new syntax, new grammar, right? So for Dart, we added, so the big one is that we added flow sensitive analysis. So if you have a local variable with a nullable type, you know, you have, you know, foo equals something that could return null. If you do, if foo does not equal null, then the type checker promotes foo to have a non-nullable type past that point. It knows it's been soundly checked. And so the type system is changing types, doing control flow analysis. And that's the thing that does most of the heavy lifting. And that's maybe something you could imagine doing for C++
Starting point is 00:45:53 where that's still part of the static analysis. But even that only really gets you part of the way, right? So we added other new syntax, right? So there's, uh, there's a little post-fix exclamation mark operator that says, I know this thing shouldn't be null. So throw an exception if it is otherwise give it to me as a non-nullable type. So then I can call methods on it. So you can do, you know, foo bang dot bar. If you're like, look, the type system doesn't know, but I know foo is not going to be null. And if it is null, throw an exception. Otherwise just let me use the thing. We added these things called late variables. So there's a late modifier on a variable declaration,
Starting point is 00:46:30 which lets you defer initialization to a runtime check. So we have, what is the term for it? Definite assignment analysis, just like I think C++ does, right? You know, you can declare a variable, not initialize it, use it later. And as long as all control flow paths initialize it, that is statically known to be safe, right? You know, you int I semicolon I equals three print I it's fine. You're never going to access uninitialized memory, right? And the language is like, okay. Um, And it's doing that analysis statically by looking at all the control flow paths, right? So we do that, which lets you, you know, one of the ways that null creeps into programs is through things that you're not ready to initialize yet. You know, you need to declare it here, but you're not ready to initialize it until farther down. Definite assignment analysis gets you part of the way there, but it doesn't work for things like
Starting point is 00:47:22 fields and top-level variables because there's no local analysis you can do to ensure that all writes will happen before all reads. This is a problem in C and C++ too, right? You can declare a module-level variable or an instance field and not initialize it, and it's definitely possible if you're not careful to end up with reading uninitialized state right yeah uh so we do definite assignment analysis for local variables where it works um and that gives you the flexibility to defer initialization um but it doesn't work for fields and top level variables so for those we added a late modifier that basically says do that initialization check at runtime. Okay. And what that lets you do is make a non-nullable variable
Starting point is 00:48:08 that you initialize later. So then you have a variable that you can use, you can call methods on because of its static type is non-nullable, but you still get the flexibility to initialize it at some point later. And the trade-off you make is that there's a runtime check that it could throw an exception if you do actually try to use it before it's initialized. Uninitialized value. Yeah. So there's just this like handful of usability language features that we added to,
Starting point is 00:48:34 to make the static analysis tolerable. Right. You know and that's kind of the, you know, kind of the fundamental trade-off of the language of static types. You know, the static analysis is always conservative. You want to make bad code a compile error, but the static analysis doesn't know what the dynamic execution is going to be. So those compile errors are always a little bit conservative. And that means that there are programs that a user writes that are dynamically correct, but the static type system can't prove it. So it yells them and that's a frustration for users right so you're always trying to like pick your static type system rules to like have the boundary of that cover as many incorrect programs while you know not yelling at correct programs and and that's hard and then just delete the incorrect code and delete the incorrect code exactly right yes okay uh i feel like we can't let you go bob until we at least mention um some
Starting point is 00:49:31 of the books you've worked on can we talk a little bit about crafting interpreters yeah we can talk about uh both books i've written two books at this point uh but crafting interpreters is the most recent and uh heaviest it's it's like the size of a phone book so it's do you have a copy right there that you could uh uh not within arm's reach but hold on a second that's all right now it's worth it hold on i've uh i've never written a phone book myself no me neither all right so uh so this is my first book it's called game programming patterns yeah that's the one so i think most of our listeners have probably heard of your book or are very many yeah this is actually uh the copy that i proofread so it's got all these like post-it notes telling me all the stuff to fix
Starting point is 00:50:14 nice um this is the size comparisons this is book one uh and uh this is Crafting Interpreters. This is the new book, and it's... Oh, yeah. That's a hefty tome. It's a lot, yeah. Yeah, it is, how many pages is it? 600? You should have named it Crafting Interpreters in a Weekend. You know, I had this idea. I went back to my notes before I started working on the book,
Starting point is 00:50:40 and in my note to myself, my initial sort of pitch for the book was like, this is going to be a small handbook, just to get users started on implementing the book. And in my note to myself, my initial sort of pitch for the book was like, this is going to be a small handbook, like the, just to get users started on implementing a language. And man, I, I missed the mark on that one. I ended up writing this giant beast of a book. But yeah, so it's, it's this book on implementing programming languages, a little bit on designing them and mostly on implementing them. Now, is this related to REN, which we haven't directly talked about yet? Mm-hmm. Okay. Yeah, it is. So sort of indirectly. So the book walks you through two implementations of the
Starting point is 00:51:16 same language. So it walks you through building an interpreter for the language in Java, using kind of as simple and kind of like, uh, yeah, kind of as simple as style as possible. Right. So it doesn't give you a very efficient implementation, but it's a good way to kind of learn the basic concepts of what it means to design and implement a programming language. And then after that,
Starting point is 00:51:34 it goes through and implements the same programming language, implements a new interpreter. Uh, but in C, uh, compiling to bytecode to a stack based bytecode, and it gives you a much more efficient implementation. I think it's five, ten times faster. So you get to do some low-level optimization
Starting point is 00:51:51 because you're writing it in. So the language that you implement is this little scripting language called LOX, and it's kind of JavaScript-esque. So it's dynamically typed, garbage collected, has classes, single dispatch, that kind of stuff. And when you implement the second interpreter in C, you have to implement all those facilities. So it talks about how do you represent objects in memory, you implement a garbage collector, that kind of stuff. So that second C implementation and the LOX language itself are both pretty heavily based on this language I made called Ren, which is a class-based scripting language. You know, my sort of initial conception of it was, you know, imagine you're a game programmer and you want to make a scripting language for your game. The canonical answer these days is Lua,
Starting point is 00:52:37 and Lua is a super cool language, but it's also kind of weird, right? You know, if you're a game programmer that's comfortable with object-oriented programming, Lua's approach to objects makes things like classes and methods feel kind of bolted on. So I was like, well, what if I tried to make a tiny little VM, something that was as easy to embed as Lua, but around a language that was designed to be more familiar and approachable to people that are comfortable with classes and objects and curly braces and semicolons. And Wren is kind of the answer to that, right? So it's this very small VM written in C, single pass compiler to bytecode. And I made this hobby
Starting point is 00:53:14 language and put it out there. And there's people using it. I don't know how many users it has. I'm not the current maintainer of it. It turns out writing a book is a lot of work. So I got a little overwhelmed with my number of side projects and fortunately was able to find a new maintainer. But so I made this language and I was like, man, you actually can pack a pretty complete language in a surprisingly small amount of fairly clean C code. And I was like, this is actually pretty cool. So then the book, you know,
Starting point is 00:53:45 the back half of the book is basically kind of tearing apart that implementation and saying, like, here's, here's how easy, maybe easy isn't the right word, but like, here's how approachable it can be to actually implement a complete programming language, right? Like, it's not this thing where like, it needs a team of 100 people working on it for 10 years, and you have to write 500,000 lines of C++ code, right? Like you really can pack garbage collection methods, classes, expressions, all that stuff, and like a couple thousand lines of fairly, fairly clean C code. So yeah, so once I kind of had that, that implementation, once I had the Ren VM, I was like, this is a thing that would be kind of cool to just teach people about.
Starting point is 00:54:22 So the locks language that the book teaches you is kind of a stripped down version of REN. It's REN with some of the weirder stuff shaved off. And then it kind of walks you through everything you need to know to sort of understand how programming languages are implemented. So if you conceptualize this as a, I need a scripting language for my game, does it in any way tie back into your game programming patterns book then it does uh a little bit so there's one of the the patterns in game programming patterns is um so there's one there's this old pattern design pattern in the original design patterns book called the interpreter pattern and it's basically like here's a way to sort of model a language
Starting point is 00:55:04 interpreter in an object-oriented implementation language. And the first half of crafting interpreters is essentially that design pattern. It's like, here's how to build a whole programming language using that design pattern. And then in my book, Game Programming Patterns, I talk about a pattern that I called bytecode, which is basically, here's how to represent some execution as a series of bytecodes, right? And it kind of abstracts away. Don't think about it as an entire programming language implementation. Don't think about parsing and all that stuff. Just think like, yeah, you have a series of instructions and you can write a little loop that just
Starting point is 00:55:38 executes them one at a time. And that's a cool way to model behavior, right? And you can think of crafting interpreters as kind of taking that little chapter of game programming patterns and expanding it to an entire book um okay and i you know part of and i think that's kind of actually part of how i got into programming languages so when i was at ea when i was writing this first book um and working on henry hatsworth uh hatsworth was like a 2D sort of platformer, kind of Mario style. Side scroller.
Starting point is 00:56:09 Side scroller, yeah. And my job, my main job was like, I was the tools programmer for it. So I made the level editor and the character editor that the game designers use to like lay out the levels, script the levels, super fun project. It was like the best basically. And the way that level editor worked is like, you know, so the game designers needed to be able to like script some behavior, right? Like you step on this platform, this door
Starting point is 00:56:36 opens, that kind of stuff. Right. And they're game designers, they weren't programmers. Right. So what I did in this tool was I gave them a little, a really simple kind of UI for kind of like a visual scripting thing where they could make, you know, a script was a list of nodes graphically that each one was like a little instruction, you know, it's like, you know, trigger this thing, send this message to this other object on screen, you know, open, shake the camera, that kind of stuff. And they would build these scripts as just like, you know, drag and drop, right? Like make a little series of nodes. And there were even control flow ones like, you know, if this monster is on screen, then do this. And there's like, you know, a little nesting in the tree and, you know, that kind of stuff. And then what the tool
Starting point is 00:57:16 did is it exported that into the game format, which is just this binary format. And it exported all those as bytecodes, right? It's just like a series of, you know, binary instructions. Um, so what I ended up building was the back half of a programming language, but not the front half. Right. So like the, the runtime execution was like a, exactly like a VM, but there was no parsing or anything like that. Cause it was all UI based. Um, and it worked out really well. I thought it was a cool system. Uh, so, you know, when I wrote that chapter in game programming patterns, it was sort of like, you can get, you know, when I wrote that chapter in Game Encroaching Patterns, it was sort of like you can get, you know, the benefit of the flexibility of something like a scripting language without necessarily having to sign yourself up for text, parsing, you know, compilation, that kind of stuff, which has a lot of, you know, good and bad consequences, right? Okay. Bob, it was great having you on the show today. We'll definitely put links to the books and references to Dart into the show notes.
Starting point is 00:58:10 Anything else you want to tell our listeners about before we let you go? I don't think so. Thanks for having me on. This has been super cool. It's fun to talk about this stuff. I know a lot of it is probably fairly tangential for your C++ audience. If you want, we can have a much longer discussion about ranting about C++
Starting point is 00:58:28 from a language design perspective. But no, thanks for having me on. This has been really cool. Thanks so much, Bob. Thanks so much for listening in as we chat about C++. We'd love to hear what you think of the podcast. Please let us know if we're discussing
Starting point is 00:58:45 the stuff you're interested in, or if you have a suggestion for a topic, we'd love to hear about that too. You can email all your thoughts to feedback at cppcast.com. We'd also appreciate if you can like CppCast on Facebook and follow CppCast on Twitter. You can also follow me at RobWIrving
Starting point is 00:59:02 and Jason at Lefticus on Twitter. We'd also like to thank all our patrons who help support the show through Patreon. If you'd like to support us on Patreon, you can do so at patreon.com slash cppcast. And of course, you can find all that info and the show notes on the podcast website at cppcast.com. Theme music for this episode was provided by podcastthemes.com.

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