heading · body

Transcript

Jon Gjengset On Rust Internals Vibe Coding And Teaching By Streaming

read summary →

TITLE: Jon Gjengset on Rust Internals, Vibe Coding, and Teaching by Streaming CHANNEL: Rock the JVM DATE: 2026-04-01 ---TRANSCRIPT--- Hey everyone, this is Daniel and if you’re interested in Rust, this conversation is going to be for you. I have John Jenet as my guest today. He’s a longtime Rust developer and open source contributor and the author of Rust for Rustations, a book on idiomatic Rust programming for intermediate developers. He’s also an avid educator and YouTuber with more than 100,000 followers at the time of this recording. And he tends to write code for extended periods of time, sometimes 10 hours at a time. And in this conversation, we’ll cover all things Rust, of course, the future of Rust, the Rust ecosystem, AI and vibe coding, education, and various other programming curiosities. I’ll let you discover. And I’m not going to spoil too much. Please welcome John Jen. John, it’s good to see you. Thank you so much for making the time.

Likewise. Thanks for having me. It’s always it’s you know it’s it makes me happy whenever I get to be talking to people for from other languages because there’s a lot of talking within the language and obviously you know part of programming is is the excitement of sharing. That’s exactly my goal for having these kinds of conversations and I’m very happy and I’m thrilled to uh have this conversation with you for this exact goal to satisfy our programming curiosity. Oh, obviously we’re going to talk about rust, of course. And where else would you want to use rust other than vibe coding? How is [laughter] how is vibe coding in Rust to your uh from your perspective? Is it more or less dangerous in Rust because of all the safety checks? So, you know, it it’s a it’s a really weird balance actually. So I would say um it’s it’s both easier and harder and safer and more dangerous. Uh let me try to explore all four dimensions. Go for it. So it’s it’s it’s um it’s harder because Rust has a fairly strict not just type system but you know the borrow checker the compiler enforces a lot of rules around um you know concurrency safety for example that if the if an LLM tries to spit out code that does not conform to those rules. It will not comply compile. That also makes it safer because a um you can’t quite as easily just sort of spit out and just have it be uh have it run and then have huge bugs in them. You can, but the bugs have to be of a different nature. And it also increases the threshold for getting something past the compiler. And when it does compile, you have slightly more of a chance that at least parts of it is correct. Um, but the ways in which it’s less safe is that you might overly rely on Rust’s ability to catch things at compile time. You’re like, well, it compiles, so it must be correct. But that doesn’t that only holds if you’ve specifically chosen the type such that that is true. And an LLM may totally not have. Um, and and the way in which it’s easy is because um I think there are two tasks that become easier when you have a strongly typed language. One of them is understanding an existing codebase. So the LLM can to a much greater extent make make extent make use of the knowledge that’s in the codebase like LSPs for example give you richer information and now that you know LLMs can read out of LSPs they give you a better mechanism for exploring the codebase and where things are used and it also makes it easier to do especially refactoring tasks because the LLM now can um you know make a refactor it breaks but the compiler tells you the way in which it breaks and then it’s able to follow the the responses from the compiler to guide it. And in fact, you know, the the Rust compiler has or the Rust compiler team, I should say, has put a lot of work into making the Rust compiler give you really good error messages and warnings. And those are useful not just to humans, but also to the LLMs observing it because the error tells you what’s wrong. Um, and so ultimately it’s like a I don’t know that it’s better or worse than other languages, but it is different. How do you use Rust in I don’t know let’s say not necessarily vibe coding but power coding like LLM assisted coding where you supervised the LLM. How has that experience been for you? I know you had these huge streams with LLM assisted coding. How uh has your experience been with AI assisted coding in general? So, um, I I I live streamed my first ever use of Agentic Coding and then I after that first video, uh, where I intentionally chose a pretty hard challenge for the LLM. Um, I then spent about two weeks where I forced myself to use nothing except LLMs basically to learn, you know, the the sort of uh convex hull of optimization, right? of where does it work well, where does it not, what what lies within the limits, what lies without. Um, and then I think since then I’ve gotten I think a more refined understanding of where is it worth my time, like where does it save me time and where is it just a waste of time. Um, and this latest stream was an example of somewhere where I had a problem and I I can go into the problem if you want, but I had a problem where I had very good tests. U I basically had an oracle that I would have to match. I have the source code for that oracle. So I it was basically a porting tasks where you already have the structure of the code. Um and the problem is self-contained enough that you you almost have a direct mapping from inputs to outputs. Um and then I had very clear directive for the direction in which I wanted it to be better than the original. Um and and I also think there was nothing super novel about the implementation here. like it was not a sophisticated algorithm or anything. It was actually a fairly straightforward sort of transpiler and so there are lots of examples in the tra of in the training set not necessarily of this particular format but of transpilers in general and so I had very high hopes that the LLM would be able to converge pretty quickly to a very good solution and that was the experience as well. Um but you know the the original stream where I gave it like what I consider to be a relatively hard task which was um trying to refactor a Rust library that is like 90% type programming. There’s very little actual implementation code and there it did terribly and I think in part because it doesn’t really understand types right it tries to pattern match and that didn’t work particularly well for this library because there aren’t really other things quite like it. You said that the you found uh LLM’s well suited for some tasks and uh less well suited for other uh things. I think you phrase it in terms of uh I know where LLMs are worth my time. Can you tell us more about that? How does that look like for you? How do you use uh these LMS in general and where do you think LM are not worth your time? At least not yet. So I mean the two questions are pretty related, right? like the places where I use it are where I think they will save me time. Um, but but I think even that there’s a there’s a bit of a a gradient to it because there are some things where I would do it faster if I did it on my own, but by having the LM do it, it will do it slower but still well enough. Uh, and I get to do something else while it’s running. And so in that sense, it doesn’t save me time, but it means that I get to do two tasks instead of one. Can you do multitasking? Can you do proper multitasking in that sense? Uh is the is the context switch worth it? At least for the It depends on what you’re working on, right? But but I would think of this more as like IO parallelism in computing, right? Where you have one thing that just like it’s just going to churn in the background and it doesn’t require a lot of computational thought from my end. It’s mostly just waiting and then every now and again I have to give it some inputs and then it keeps going. Um, and then I can do the sort of compute every task where I actually need to use my brain a lot. But that assumes that I can find a task where the LM is relatively self-going and where the um the cognitive context required for me to supervise it is relatively low and those don’t come along all the all the time. So the better tasks are the ones where it actually is faster than me, right? because there even if I like I’m I don’t then I don’t use it in the multitasking sense. I just do that task and it’s just way faster than I would have been on my own. And I you know I I’ve I have examples in in both cases where um you know the the LM has delivered on that promise and then I have a bunch of things where it it can’t do either and I just wouldn’t use it for these. I’m curious. I wanted to uh ask how or whether you code on your own, but now that you’ve mentioned that you have examples, I’m very curious to hear him. Yeah. So, so things where it does really well on its own um are places where and especially if you if you want it to run for longer periods of time like actually accomplish a bigger tasks are the ones where you have a very strong if not oracle like you don’t have a a golden solution where you say for every input it must match this output but even if you have something that approximates it where you can write a set of very well-covering complete test cases almost like test-driven development and then you say, you know, write me a solution that meets these tests. And if something meets those tests, you have high confidence that it’s correct. Anything like that, you can get it to iterate quite well on its own. And it’s going to come up with a bunch of stupid solutions because it does it basically does a random walk, right? A semi-random walk, um, is at least the way it’s modeled in my head. And so when it does the semi-random walk, it will run into a bunch of stupid solutions. But if you give it both um criteria for what it should optimize for and sort of limits on what does a correct solution look like, then it can actually iterate quite well to get to that solution. Um it it depends a little bit on whether it needs to come up with algorithmic insights because usually it will not like it won’t invent you a smarter algorithm for something. But if there’s like a a program where the code that needs to be written is mostly like a you know all the solutions exist out there already. They just need to be assembled into the right order and then you pattern match a little bit and and pattern replicate a little bit and then you get a solution then it can work really well for that. Um and so this is where that transpiler I built for example for this was for in the AVO um AVO is a an interface definition language for like RPC style things think similar to protobuff um and I wanted a transpiler from the Avro IDL language to the AVO JSON schema representation and it’s like there is a Java version that works just fine. and it gives you it’s it’s a perfect oracle and so I can say what perfect looks like and then I can give it optimization criteria and then I can just kind of tell it to go and you know re redo it more and more until you further optimize the optimization criteria. How how often does that happen? uh is this correct specification or these this complete specification does that occur often for you or do you have to spend quite some time to I don’t know about often yeah I’d say you know it happens to to a greater or lesser extent like sometimes I hit like sort of hit gold where I hit something where it’s just obvious that it will do great at this task and then many times it’s like this part of the problem I could do this for, but these other parts not so much. And the reality is that if for any given project project I’m working on, there are like some parts that work really well, some parts that don’t work at all, and some that are a little bit in the middle. And you kind of need to use your brain a little to figure out, you know, how to partition the space into LM work well here, LM do not work well here. And the distribution within any given project is kind of hard to kind of hard to predict. Like for an example of something that sort of fell in between um I so there’s this tool called touchportal that is basically a you know you’ve seen these like little stream decks so not a Steam Deck but a stream deck. They’re little screens where you can like remote control things like OBS or YouTube streams and stuff. Those are super expensive. Um but there’s an open source thing called Touch Portal that tries to do the same thing. So it basically gives you an SDK for writing applications that can show little icons on a grid on a mobile phone app or an iPad app and you get basically the same functionality. And so I wanted to write a plugin there that gave me like buttons and state and stuff in this touchportal app for controlling a YouTube live stream. And this is something where the YouTube API is like very widely used. There are in interestingly enough not very many good support libraries in most languages. And I don’t know why that is. Maybe it’s because the API is kind of weird. Maybe it’s because it’s kind of simple. Uh maybe it’s because it’s kind of hard to make a good ergonomic mapping to them. Or maybe they just didn’t bother writing a good one in Rust. I don’t know. Um but this is something where there exists so much code that uses this API that the LM is fantastic at generating code that uses it. So I can basically just tell it, you know, here are the things that I want out of the YouTube API. Uh, and it just generates all the code for me. These are the things I want to be able to edit. Generates all the code for me. But for the part of um interacting with a touch portal SDK, this is an SDK it probably has seen almost no code for. And so there I had to write out quite a lot of the SDK surface. I had to write some like Rust code generation because I wanted it to be type- safe and those things it was really bad at. And then when it came to combining these like bind these two APIs together, then it worked decently well again because it had the the all the SDK code for YouTube that generated I had well documented the touch portal SDK side and then the glue in between like this kind of glue code where both sides are well defined it does pretty well on but I need to sort of instruct it on yeah I want the semantics of this button to be this map to that. So I it required some amount of user input from my end like as an enduser what do I want this to do but not so much computational context right um you said something that [clears throat] while trying to force yourself to vibe code and just use LLMs you developed a kind of sense or a taste for what’s worth um delegating to an LLM what’s worth taking on yourself how does one train themselves to get the the kind of internal feeling or the uh spidey sense that you’ve got. How would you advise somebody to get that sort of I think I would give this the same vice advice I followed right it’s like immerse yourself into it for two weeks and use it for everything even places where you feel like it makes no sense because then if you force it yourself to really use it for everything um it will show you a bunch of places where you were right it was useless a bunch of places where your intuition was maybe right that it would be really great at it. But then you’ll be there’ll be some cases you’re surprised by. There’ll be some things you thought it would be good at, but it’s really bad and some things that you thought it would be bad at that it’s really good at. And that’s how you learn, right? It’s from those two latter categories. And you only discover them if you force yourself to use it for all the things. And it doesn’t actually take that long. I mean, depends a little bit on how actively you program and also the diversity of things you program on in a given span of time. But for me, two weeks was about right. like I’d worked on enough different code bases that over two weeks I was like okay I feel like I have a rough shape on this and then obviously the understanding gets refined over time right so I have a better understanding now that I had immediately after the two weeks but it’s because you got to like build your initial intuition pretty quickly I can segue that question to Rust itself how would you advise somebody to gain a sort of internalized idiomatic understanding of how good Rust code should be written and I’m asking this as a Scola developer because at the time when I started writing Scola it was about 10 12 years ago and people were excited about Scola they were coming from Java and a lot of that Scar code was basically Java mental model with the SCA syntax and that was proven I mean it it was obvious from the very beginning that was that that was a bad model, but it proved worse as time went by. And so I could ask this question for Rust. How would you instruct or how would you advise somebody learning Rust to learn good idiomatic Rust rather than getting bad mental models from other languages. So the Rust has a slight benefit here or a slight uh trick up its sleeve which is that if you try to do things a nonidiomatic way, you will eventually kind of get stuck because the compiler will not let you get away with doing some things that would naturally fall out of writing Java in Rust for example. um less so with with C to Rust, a little bit with C++ to Rust, but there are a bunch of patterns where you would write in those languages and if you try to write code in that way in Rust, either it just will not compile or you have to pull a bunch of hacks to like make it compile and you have to like clone everything and arc everything and mutx everything. Um and then you know a little bit further down the line you have to modify your program and now you have even more arcs and even more mutxes and now you have deadlocks because the things lock you know um you you end up with like a deadlock situation where you take the locks in a different order or you take one while you hold the other and something else expects just the interlock and you get into all these like really painful problems that it makes you feel like your application is like architectured in a way where the language dislikes it right like it it’s it it becomes painful to program in and I think when you hit that point and and I think everyone does who goes into the language from a language that is that doesn’t have these same rules when you hit that point you have sort of two paths you can either go well screw this language it’s bad I don’t like it it’s really annoying to write I have to arc mutx everything why is everyone doing this I’m going to stop writing Rust Right? That that’s one path and there are a bunch of people who go that path and then I think the other path is you go I think the language is trying to teach me something here and then you try to figure out how do I change my application so that these problems don’t manifest in the first place and the first time you do that it will be painful because not only do you have to learn like unlearn some of your language things from the previous language and learn some of the genuinely new Rust concepts like lifetimes which don’t exist in other languages. But in addition, you have to rewrite so much code because everything you’ve written up to that point, large chunks of it may need to be if not fully refactored, at least slightly changed to introduce this notion of lifetimes and borrows and send and sync and like getting rid of a bunch of the arcs and mutxes. You might have to change which threads handle what work and how the work are distributed and like it be it’s a pretty decent chunk of massaging your code. But the advantage is now you’ve learned the lessons for next time. So the next time you write code, you will do a little bit more of that massaging proactively rather than reactively. And you’ll probably get to a point where like this feels hard when it shouldn’t be again. And now you again have the choice of do I give up and go ah this just proves that even when I try rust is painful or do you then try to learn the lesson again and then you know adapt your coding to fit and I think there’s a there’s maybe an interesting sort of programmatic philosophical question here of if a language is trying to teach you this many things is it because the language is just bad and I can like look sideways at languages like Nyx here or Pearl um right where like you have to learn a bunch of things but it’s not clear that it’s because the language is smart. It’s just because they’re kind of annoying. Vimcript falls into a similar category. Um but but my experience has been that the programs that come out of adapting to Rust’s way of doing things do produce often better architected programs. like the the internal structure of the program is actually better, easier to refactor in the future, more modular, higher performance. Like it tends to push you in in directions that are useful, not just like it forces you to not do things your way, but the way it pushes you is often better. Not always, but often. And then the other is I think it has taught me something. It’s like there’s the borrow checker is kind of built into my head now in a way that other parts of programming languages built have been built into my head in the past when working with other languages. And I think it makes me better at writing other languages now. if I now go and write JavaScript code for that matter like the borrow checker in me kind of kicks in when I write the code and I go but how will the compiler be able to free this memory in a JavaScript that’s not a thing but it kind of is because otherwise you end up with things like garbage collection loops and you end up with things that never get deallocated so you end up with memory bloatin applications and all of the these things do matter in JavaScript land too but there’s like very many steps down the line before that’s a thing you even know to look for in JavaScript Whereas for me that’s now a proactive part of my brain because Rust requires it to be. How much or to what degree did the Rust team bake the philosophy of Rust to avoid that fork in the road where people go like Rust sucks because I can’t write things the way that I used to write and guide them or hurt them towards what idiomatic rust should otherwise be. Because let me give you an example from the Scola world. We also have that fork in the road because Scala has a lot of features. It has has a very rich type system and it’s very tempting for a newcomer to Scala to say Scola is such a complex language. I hate it. I it’s very hard for me to fight with the types until I get an HTTP server up and running and I serve my first get request and things like that. Uh, and I’m curious to what degree rust as a philosophy tries to bring people slowly and gently towards the, hey, this is something that I want to teach you rather than telling me that the language sucks. H, how does that go? Yeah, you know, I don’t think Russ is particularly gentle about it. And I don’t know whether this was a an intentional choice or whether it was kind of a there is no gentle way to do it but Rust is like quite opinionated. Um so so you see this all the way from the language itself where a lot of things are compiler errors right like you just they just won’t let you compile things that you shouldn’t do. Um, but to the point that things like the so the cargo, the package manager for Rust also has a bunch of built-in fairly strong preferences for how you’re supposed to package code, build code, version code that might come across as constricting, but it it it is because they wanted a very opinionated system for people to build on top of. And I think that’s been to the language’s advantage, but at the same time, it does make it frustrating to learn for the first time. And I think the way the Russ has tried to soften that very opinionated stance on many things is to then relentlessly focus on good documentation and good tooling and good error messages. um because it means that when you do get that you know the compiler refuses to accept your program at least it will tell you why and it will try to tell you in decent amount of detail. It’s why you have uh the standard library documentation in Rust in general is very good, right? When it’s easy to access, it’s very standardized across the ecosystem. So, it’s pretty easy to like look up the typing question, look at the APIs, look at the function signatures, and get a description of what it is, what it is, and how it works and why. Um, and and I think that that it softens it, but it’s not going to get someone to um, you know, if you’re very set on I need to do things my way and the way I’ve always done it. Rust is not the language that lets you do that. It doesn’t provide you with a lot of escape patches in that direction. Yeah. It’s gonna fight with you one, right? It’s like, well, it provides you one escape hatch, but it’s a it’s a very uh obviously sharp knife, right? It’s a very sharp tool on purpose that’s documented to be so so that people don’t reach for it easily. That’s a very interesting and I think that’s that’s on purpose. What are some habits that you’ve seen newcomers to Rust uh apply to Rust code that they should unlearn in order to produce good Rust code? It it really depends on what language they come from. Certainly one thing we see a lot is the um the object-oriented programming mindset of like I’m going to have like traits are kind of like classes so let’s treat them as classes and then I want inheritance so I’m going to have traits that are super traits of other traits and then you you start constructing it this way and it like kind of looks like it works until you hit into a bunch of things where it’s just not the same like you don’t need to worry about things like DI compatibility in Java classes that’s not a thing but in Rust traits don’t that’s not what they do there’s like a bunch of things that you get from classes the traits do not give you the same thing if you try to use um you know types with generics then trying to treat generics as like class inheritance also doesn’t work um but you get these these APIs and these applications that are built where the the types are used to represent objects, but Rust doesn’t believe that that’s how you should structure types. And so then you run into all these problems down the line where you try to use them in that way and suddenly the borrow checker tells you, well, you can’t access that field and this field at the same time. And then you throw up your hands and you go, but I want to I need to because that’s that’s what my class is. Um, and I think the the other one we see a decent amount of is um, Rust tends to want you to write code that cares about performance, right? Like the language nudges you in that direction a lot. Um, and I think people tend to take that a little bit too much to heart. So they think well it gives me all these like low-level language gives me all these low-level tools and I don’t have a runtime or anything so I should really think about the performance and I think they get little sort of blinders on a little bit and they think I must maximize perform performance everywhere instead of using the you know um the thing that’s obviously slower and the documentation will tell you it’s slower and it will feel slower but it’s like the correct thing to choose for your application because you’re writing a web application is going to serve like 30 requests a minute. So, it doesn’t matter. And I think um that that error of you know turning the performance stick to maximum and therefore the ergonomics to the lowest setting uh is a trap I think many people fall into when they first start working with the language. That’s very interesting. um because a lot of programmers come from object-oriented languages like even JavaScript uh not to mention the Javas and the CS and the even the C++ to some degree. Um it’s funny though, JavaScript also is not really object-oriented, right? It’s like a prototype language, right? And so technically it doesn’t really fit class inheritance. And you notice, right, if you try to use object-oriented orientated programming to like map out something in JavaScript, it kind of looks like it works, but it also doesn’t. It’s weird. It feels weird. It behaves differently. I’ve been studying Rust for a while, and um when I read about traits for the first time, Skull has this notion of a trait, which is the uh equivalent of a Java interface with just methods and stuff. um to some degree it’s similar in Rust but when you implement a trait in Rust it’s not the same as inheriting a trait in object-oriented terms. So when I read about traits in Rust when you implement the trait for a specific type and not for others I go like type classes. Why or how did Rust uh arrive at this design? Where did it get its inspiration from and why this particular choice? Um, I mean I I think the the I don’t actually know where the original design came from. I think it from was from Haskell as like type classes from Haskell, which is what they are. Um uh why they went with this kind of design instead of object orientation is not immediately obvious to me, but the closest I can think of is the borrow checker does not really want you to divide um to divide your state by object because if you do, you run into these really weird situations where you know I want mutable access to these these fields concurrently with these fields from like these other fields and um the borrow checker does understand that one field of a strct is separate from another field of a strruct. But if you borrow one field into one function and then you try to borrow a different field um sort of in a in a uh what’s a good example of this uh okay one limitation of Rust today for example is when you implement a method on a type and that method wants access to the fields of the type it takes a mutable reference to self but the mutable reference to self is a mutable borrow of the entire object, the entire type instance. And so if you have a a method like that and you um get a mutable reference to some field inside of that method and you call some function with it, then that that’s considered as borrowing the entire type. And so you can’t call that mutable function while also calling some concurrently some other mutable method on the same object because even if that method uses different fields, the borrow checker, all the borrow checker sees is that they both mutably access this this type instance, this entire strruct instance. And so in a way this is a limitation of the borrow checker. But conceptually what the compiler is trying to tell you is you have two method calls that both think that they have exclusive access to this strct item. Um and Rust won’t let you do that. And so the language, you know, if if you lean into object-oriented programming, you would end run into this case a lot because you have all this state that’s really it’s only related to each other in the sense that they’re part of the same object, but they’re they’re unrelated to each other in other ways. And so Russ would rather you break up the state by things you’re going to access concurrently rather than any kind of mapping to objects. This is a I I I this is a very nice answer because I never would have thought that object orientation was in this case let’s just call it at odds with this necessity of accessing different parts of the same object. uh for example concurrently as you said. [snorts] So yeah, I mean it kind of makes sense. What are some other borrow checker limitations? Uh and when do you absolutely need to avoid that? For example, with unsafe. Um so the most obvious case where you need to reach for unsafe is when you are implementing concurrent data structures, right? So if you’re trying to implement for example a concurrent hashmap then you’re writing code where a shared reference so an alias reference to the map should still allow you to mutate the map and normally rust bar will just disallow this it will say you’re trying to concurrently access this you know memory allocation and so you’re not allowed to modify it you can only read it whereas if you’re implementing a concurrent hashmap the whole point is that the data structure and the algorithms around it are made such that that concurrent access is actually safe. And so that’s where unsafe comes in. Like the the unsafe keyword in Rust is really for uh telling the compiler like trust me I’ve checked this is safe. Unsafe does not mean let me do whatever I want. Right? Unsafe means I prom dear compiler I promise I solemnly swear that I have checked this code and it follows all your rules. And it’s needed because there are a bunch of invariants that the compiler cannot check for you. For example, invariants that have to be checked at runtime, but you don’t want to incur the runtime costs, like by having a mutex. And so therefore, you have to like design the algorithm so that it cannot fail at runtime, but the compiler can’t check that for you. And there’s an extreme version of this, right? Where you use like formal methods or something to actually prove that your unsafe code is safe. That’s really what Rust wants. But in the absence of that, it’s like you put unsafe around it. You write a comment explaining I really checked. What is some good unsafe hygiene? How do you prevent abuse? Because it can very easily go to something like hey compiler I promise I’m going to behave and it just goes I’m going to do what whatever I want. And that happens that does happen. Um so the there are a couple of things that I follow. The the first of them is unsafety is intended to be encapsulated. So if you have a codebase that’s like you know in Rust one unit of code is called one crate. You think of that as a library or a binary is one crate. And um if I have one crate that has a bunch of unsafe code and also a bunch of safe code, that to me is like code smell because I would expect the unsafe code to live at the very least in its own module, but ideally in its own crate and have a bunch of internal unsafety, but have a safe external interface like its public API should ideally be fully safe and its internal should be unsafe. And you see this a lot in the standard library. For example, like a mutex under the hood internally is unsafe represents a fully safe interface. Same with a hashmap. A hashmap internally is a bunch of like random pointer d references and buckets and like pointer arithmetic. All of that is unsafe, but it presents a fully safe interface. And that’s the same thing I expect from any other code that tries to use in safe too. You should really try to figure out what is the safe encapsulation of this. Um and then step one uh step two rather is um was zero index to step one. Step two is to for any unsafe code you write to mandate that there are safety comments above every such unsafe block. So if you think of there’s like really two instances of the unsafe keyword in Rust. There’s you can put unsafe in front of a function to declare this function is unsafe to call and then you can declare unsafe for a a piece of code and that declares this code uh methods inside of it are unsafe to call and this is my statement that I have I have checked that those are safe and so for any unsafe block of code you write a comment explaining um you know I have checked all the preconditions of the methods that are inside this block and I satis satisfy all of them. This is like my proof that this code is safe in in human language. And for any unsafe function, you document what are the preconditions that must hold for this to be safe to call. And so it basically becomes a sort of contract negotiation, right? Where the the safety comment on the unsafe function is what do you have to promise? And the safety comment on the unsafe block is here’s proof that I meet all those things I have to promise. Do you enforce these in the third one is really solid testing, right? So we have we have pretty good testing tools in Rust especially for unsafe code. So we have this thing called MIRI uh which is the uh middle intermediate representation interpreter. So it takes like a half compiled version of Rust and it runs it through an interpreter and because it’s an interpreter it it runs a lot slower but it can actually observe every memory operation every arithmetic everything and it tells you if you ever do any operation that’s actually unound. So anything that’s undefined behavior like reading from memory that has not been initialized or you know two functions that both access memory mutably uh without any kind of synchronization primitive in between. Meri can detect all of those. And so if you have a good test suite and you’re in Meri over the test suite, it will tell you if you ever triggered something that Rust would considered undefined. That’s very cool. I mean, this is as good a hygiene as you as you can probably get. Do you enforce these in PRs? I I assume that this is standard behavior to just document everything, separate safe, unsafe, encapsulate things. So you would expect so, but it really depends on the author. These are the things that I think you need to do when you write unsafe code. But there are also people who treat unsafe as pestilence and they don’t want anything to do with it and declare like deny unsafe at the top of their thing. So they want no unsafe code in any anything they write and that’s fine. I mean ideally we’ve built an ecosystem where most people should not need to write unsafe code because there are safe library that abstract that away from them. So actually I’m fine with some people having that attitude. Um and then the the opposite case are the people who go ah unsafe is just I just lets me write C and so I’ll just use it a bunch. Um that that’s that’s an attitude too. Uh I don’t particularly agree with it. And then I think you have people in between who go yeah unsafe is something that you know obviously it’s more dangerous to use unsafe but they don’t necessarily want to go to all the trouble of like documenting every block running all these extensive test suites that take forever uh or enforcing it in CI. Um, usually I I fall pretty close to the enforcement side. So for anything I write that is is sort of a primarily unsafe crate. I will have CI runs MIRI over the test suite. I’ll often use um if it’s concurrency based, I’ll use things like Loom which is a a concurrency checker in Russ that exhaustively checks every possible interle of your concurrent code in addition. Uh so I’ll run that with like debug assertions enabled. Um, I will. So, the there’s a tool in Rust called Clippy, which is the the Rust linter. And Clippy has a bunch of lints that are off by default, but you can enable if you wish. Um, and one of those lints is to lint for safety comments above unsafe keyword uses. And so I turn that on for those repositories. Um, and so you know where you are on that scale I think varies, but that that’s what I consider what I want unsafe libraries to make use of. How long did it take for you to get the borrow checker built uh burnt into your head? [sighs] It’s hard to say when it happened because it was a very gradual process. So I I started using Rust in late 2015, early 2016, so pretty quickly after 1.0. Um, and certainly initially I ran into it a bunch and that was partially because I was unus to it. Um, and the other reason was the early borrow checker had a bunch of known limitations that would actually hit you pretty quickly. Um, the current borrow checker is a lot smarter. So there way many cases it can figure out on its own and it understands so the program is actually correct. Um but there are still bugs where if you write very particular code patterns the bar checker will tell you this code is invalid and you know that it’s not but it’s much rarer. But so back then certainly in the beginning I I felt like this is uh this is a bit of a chore. I’d say, you know, maybe after after six months, it didn’t really feel like a barrier. Um, but but I think like the point where I my brain was like proactively running a borrow checker while writing code is like a year maybe. I think it depends also on the kind of code you wrote. So, so like during that time I wrote code that was very stressful for the borrow checker. Uh, so I was writing like a a database engine from scratch and a query optimizer from scratch. And so there’s a decent amount of like low-level performance optimization. There’s a lot of like, you know, tweaking with network protocols and like binary des serialization, like a bunch of those kinds of things where you have to run a bunch of unsafe. There’s a bunch of weird borrow check corner cases. A lot of concurrency. There’s a lot of cases where you don’t want to clone or copy data. You don’t even want to like memcopy things because it’s on the critical path. is you want to borrow with pointers, but you ideally don’t want to make that unsafe. And so there’s like a lot of wrestling with exactly what the borrowing rules are. And so that burns it into your head a lot faster than if you’re writing just like a web front end of some kind. What is Palonius and uh how is that uh getting built into Rust as the new borrow checker? Um so I always get Palonius and chalk mixed up. I think Chalk is the new trait checker and Pelonius is the new borrow checker. They’ve both been under development for a while. And part of this is because um there’s like not many people who study this for a living and can work on it full-time. Um and it’s fairly like nuance and some of it kind of state-of-the-art stuff. In addition, whatever you introduce as the new trait checker, the new borrow checker needs to slot into Rust and no current code should stop compiling, but also no unsafe code should be allowed to start compiling. It’s there’s like a very narrow gap for correctness. And so that means there’s a there’s a huge amount of work to make it both backwards compatible and safe. Um, and as a result, I mean, Palonius has been in the works now for, I want to say, five years, maybe, maybe even more. Um, and you know what what it what it promises is not actually to change what’s currently allowed by all that much, but to make it possible to have finer grained borrowing. So an example here would be the example I gave earlier of if you have methods on a on a strct that currently they can only mutably borrow all of self. But one of the things Pelonius as I understand it will be able to do is I mean this would be an extension to the language but this would enable that extension to the language is to be able to say this method mutably borrows only these fields. And so if if you want to call another function that borrows a a disjoint set of fields, that’s allowed to happen concurrently with this one. Um those borrows are allowed to coexist. And so it’s more about having um more probably control fine grain. It’s like fine grain tracking but also more sophisticated reasoning about the borrowing rules is what Paloniius will eventually buy us. Is that is there a uh a timeline for Palonios to be integrated into Rust? I I couldn’t find any. I I tried to No, not not that I know of. I mean, it I know it stagnated for a few years because there wasn’t anyone actively working on it. I think it started to pick back up now. Um but it’s still a relatively small group of people working on it. I I don’t I’m not sort of holding my breath for it anytime soon. But at the same time, I think part of the reason why the work on it has been somewhat slow is also because the need is so much less than it was for the previous new iteration of the borrow checker. So in the Rust 2018 edition, we got something called non- lexical lifetimes. And that was a huge boon to the expressivity of lifetimes in Rust. um the the borrow checker that had lexical lifetimes before that was it was very easy to write code that the borrow checker would reject erroneously. Whereas with this the non- lexical lifetime borrow checker most of the time if the borrow checker tells you your code is invalid it’s probably right. Um so so the the the motivation for making something better is is reduced. What are some features that Russ has deliberately uh deliberately avoided and why do you think that is? Um so so I think there’s some on the standard library side and then there’s some on the language side. So on the on the standard library side the the Rust standard library is chosen to be very narrow but very deep. So, for example, like there’s no regular expressions, there’s no randomness, um, which bothers a lot of people. There’s no like concurrent hashmap, there’s no HTTP server, there’s no cryptography. Um, like there’s basically no batteries included. But what they do have is they have um, you know, a lot of the the data structures that you expect to be used in like almost any application, right? You have you have hashmaps, you have hash sets, you have binary trees, you have binary heaps, you have uh channels, mutxes, reference counted atomic reference counted things like a lot of those and then option result a lot of the algebraic data types the rest is very useful for and those have an like truly endless number of methods on them to cater to every possible use case. The same thing if you look at the the numerical types in Rust there’s so many um Oh, excuse me. Um, there’s so many predefined methods that give you things like anything that you would reach for like assembly instructions from like count the number of trailing zeros in the binary encoding of this integer, right? Like those things are all in the standard library on the standard integer types. So Russ has chosen that path and I think part of it is this feeling of they don’t want to standardize things where the API you might want to evolve over time right and this is something I think you see in in Python for example which is much more batteries included in the standard library and I think to an extent they’ve been bitten by this right because it means that there are parts of the standard library that have sort of fallen by the wayside because no one thinks it’s the best implementation anymore in part because it can’t really be made the best implementation because the API isn’t right but you can’t change the API because it’s in the standard library and so it’s not versioned so you would need a new major version of Python which we all know we’re not going to do that again right so so the this sort of came upon this trap and I think Rust observed that happening and went we’re we don’t want that to happen to us um and I think on the on the language side um I don’t think there’s lots of features that Rust is sort of uh excluded from the language. I think the closest would be things like green threads. I mean, we have futures. We have async. Um but there’s no there’s no runtime for them in the standard library, for example. And I think it’s relatively unlikely that we’ll get that. Um so, so that’s certainly an intention of something not to include in the language. I think another one is um we generally don’t have um well this is something that we might get but it’s a little unclear is like uh runtime reflection of types. So Java you know for example you can like interrogate an object at runtime and ask it what its type is and then ask what fields that type has. Some of the most famous some of the most famous programming frameworks in Java are built on that, right? And I mean you have more extreme versions of this, right? Like in in uh both in Ruby and in JavaScript where you can do not just duct typing, but you can do like monkey patching where you can override the methods of the thing at runtime for a specific not even a type but an instance of that type. And it like gets really funky. Uh and Russ has just said we’re we’re not having that. Um we types are a compile time thing and we we are getting to an extent now compile time reflection. So in code that runs at compile time, you get to introspect types and then ask for what fields does this type have and everything. But you don’t have the same mechanism at runtime. And that is very much a an intentional decision. And it’s also something that would be very hard to enable in Rust because of the other thing the language doesn’t have which is a runtime. Um and I mean runtime here includes things like garbage collection includes things like uh an async runtime. Like all of those things are roughly runtime shaped. Um but I think run rust realistically is never going to gain a runtime. And it’s because there are a bunch of things that a runtime forces you to trade off that Rust isn’t willing to trade off, right? is like predictability of what happens when you compile your code. It like runs the same always. It’s overhead in terms of you have control over things like there are no GC pauses. There might be other pauses but because of your own code, not because of some ethereal code that runs in the background. Um but but it comes with a cost, right? Like there are then now a bunch of things that you don’t get to have green threads in an ergonomic way. You don’t get you have to do reference counting because you can’t have like automatic garbage collection cleanup. Um but but that’s a trade-off Rust made very explicitly. How did teaching Rust come about? You wrote Rust for Rust stations. I wanted to ask what prompted the creation of the book and what did the writing of the book give you in terms of your own clarity? And I’m asking this question from the point of view of somebody who teaches uh some difficult programming topics uh for a living. uh I I do uh courses I make courses in rock the JVM and I know for a fact that while creating teaching material I I thought I knew uh the topic at hand but while teaching I got so much more clarity while delivering that thing and I’m wondering how the process of writing rust for stations went for you and what you got out of it in this context so my my rust educational journey began I want to say in like 2018 that so Russ does these community surveys every year. Uh and in that community survey one of the things they asked was what is the thing most missing from the Rust community? And the overwhelming answer was educational resources for intermediate programming in Rust. Um and I was like well I’ve written Rust now for a few years. I feel like you know I’m I’m decently adept at the language. I also like doing education like that’s something I’ve I’ve liked for a long period of my life. I was you know in a PhD program so I had the time and I had also the sort of motivation to do teaching because that’s what I was doing uh sort of separately as well. Um so you know between time and motivation and skill I figured okay maybe that could be me. Um, and initially I asked the community and by that I mean I I tweeted out a poll um of where like what kind of resource would you want to learn intermediate programming and the overwhelming response from like and I’m talking like six people replied. So it’s like it’s a very fluke right in the in the early days uh was we want live programming videos of someone who shows us what the experience is like going through intermediate programming. Show us when you get stuck what you do, show us the programming patterns you use. Explain how you think. Explain how you reason through problems. Explain how you read code. And so that’s how I started my my YouTube um channel where I do exactly that kind of intermediate programming. But that ends up being very long form, right? Like my videos, I I have programming videos that are like 8 to 10 hours long where I sit and program things. And for some that is an excellent way to learn because you basically get to like, you know, look over the shoulder of someone who’s done this a lot and get to see an experienced programmer work and learn from that and sort of learn by osmosis. And I think there are a bunch of things that you learn because no one would think to teach them because they’re so small or you don’t even notice it’s a thing you do. But if you’re an a beginner or someone who’s sort of starting intermediate, you get to observe them. You go, “Oh, I learned that. Oh, I learned this little trick.” And there are so many of those as you just work normally. But I got the feedback that there were a bunch of people for whom like they just don’t have the time or patient to sit through those videos or they don’t have the attention span or it’s just like not their preferred medium. They would rather read at their own pace than have to sort of be walked through code where they might not care about the code. they care about the principles and that’s the videos don’t f focus on the principles. Um, and you know, I mold this feedback over and was like, well, maybe written materials would be the way to go for these people. And around the same time, um, No Star Press, which have made a bunch of other programming books, reached out to me and said, “We’re thinking of releasing.” So, they are the ones who worked on the original Rust book. So, um, the the one that sort of for introduction to the language, this is the Rust book. Um, and they were like, “We’re thinking of doing a a volume two, if you will, for intermediate programmers, and we see you’d done a lot of intermediate programming. Would you be interested in writing this book?” And it the timeline sort of aligned, and I was like, “Sure, I’ll try to write a book. That sounds interesting.” Um, I I signed up for doing that basically the same time as I was writing my PhD thesis. So, it was a a lot of writing at the same time. Um but but you know it was this perfect um coming together of building some advanced software in Rust, working a lot in the Rust community, doing education in other forms and then going well let me just write it down while I do it. Um and you’re totally right. I’ I’ve learned an enormous amount both from those videos but also from the book of trying to write down concisely what are the insights um because it’s very easy to just sort of go on and on and in pros about writing code but when you have to like distill the insights and write them up in a concise but understandable way it it forces you to have a deep understanding so that you say like the the accurate words in the right order. That’s a good certainly a learning experience. The right words in the right order. That’s basically what good writing is, but it’s very very hard to do. At least it was for me. I think it’s actually even worse than that. It’s the right words in the right order with no extra words. Yeah. And it’s the with no extra words that’s particularly hard because most books are edited to at least half the size. I know. Uh I know that’s a common practice even without I mean non-technical books probably especially uh cut down most of the original draft and uh especially for a teaching um for a teaching project you do need to be precise and you do need to use the attention of your reader slashwatcher very very carefully and I have a similar experience with videos and I was curious how that process This was any difficult parts in writing that book. What was something that took a long time? Um, took a lot of effort. Intermediate programming, right? Is that it’s inherently a very broad topic because when you’re a beginner, you’re trying to learn like the basics of the language. But when you become intermediate, intermedi can go in a lot of different directions. And if you want to write a good general purpose intermediate resource, you need to go into all of the rabbit holes. Um, and so a a big part of it was figuring out which of the which sort of sectors should I tackle and which ones do I just have to declare out of scope for now and how deep do I go into each one. Um, so that was certainly a journey and then the other one was uh how user friendly should the book be? So you know when we say intermediate intermediate is a very illdefined segment of programmers because that spans everywhere from just after having read the first book to I’m an expert in Rust and like that’s a huge gamut to spend. Um and you know what I landed on was I want this book to be I I don’t want it to be the exhaustive guide to any topic. I want it to be the thing that tells you about the core concept that you can go read more about if it’s relevant to you. And so as a result, the book is actually very concise. Like I think it’s shorter than the Rust programming language book. Um it’s shorter than a lot of programming books, but it’s extremely dense. Um, and I I you see this if you read the reviews for the book, which you know I I do because I guess I like self torture, but also because some people say nice things and that’s nice. Um, but I’d say like the majority of critical reviews that the book gets are from people who go, uh, this was too dense. Like it needs more diagrams. It need more explanation. It needs more context. Like I read the same page like 17 times before I understood it. And in a way, that’s sort of what it was written for. Like that’s that’s the intended e user experience is that it’s dense. You read a paragraph a bunch of times, but eventually there’s enough precision in there that you’ve actually learned the concept. And then if you want to learn how to apply it, well, now you know the core concept and you can now, you know, the words, you can go Google them, you can read other resources. The book should not be the exhaustive resource. And then I’ve did that for topic after topic after topic. And so as a result it becomes very dense. Um and so so that was difficult of like how dense is too dense. Um and then I think the other one was I wanted the book to be uh timeless is too strong but especially in the early days of a programming language a lot of things change especially in the community in the ecosystem. So I wanted to make sure that this book would still be useful 5 to 10 years later. And that meant there are bunch of things that are standard in the Rust ecosystem that I don’t mention in the book. It’s very focused on the language and the standard library and the tool chain and not things like you know at the time there was sort of still debate over whether you know there were multiple like serialization frameworks in Rust. Uh there was one called Rust Serialize and there’s uh Certi and at the time they were both like still it was still unclear which of those were going to pan out or whether another one was. I mean now there’s no question is like the thing that’s used everywhere but I didn’t want to encode that assumption into the book as there’s a bunch of libraries that probably should be mentioned but aren’t on purpose. smart choices because you never know at the time what’s going to pop out and uh that in turn will probably make a chunk of the book um let’s say outdated or irrelevant irrelevant yes so what would you teach a so if you were to instead of a 10hour stream where you dive into a very specific problem very deeply uh somebody basically watches over your shoulder sees your screen. Uh, if you if you had 10 hours of a an intermediate programmer has not seen Rust before, what would you cover in a 10-hour video or series? Um, if you wanted to teach Rust, of course. Yeah. I I um so I would never watch my own videos is is a thing I concluded very early on. Like I don’t really watch like live programming. That’s not a thing that interests me. Uh or or rather I don’t know that it’s is that it doesn’t interest me, but rather that’s not the way I learn. I learn by doing things myself. Uh and that’s the only way I learn. And so I know that if I watched that stream, I’d be like, well, I want to go code this thing now. I don’t want to watch someone else do it. And then I think that’s partially because I enjoy getting stuck. I enjoy the like the language is trying to teach me something. Let me go figure out what it is and like debugging like I like that loop. But I think that’s partially because by now I’m a fairly experienced programmer so I can get myself unstuck fairly easily. You know, modulo the hard cases, right? Um I think if you’re more towards the beginner side of the spectrum or if you learn more from um examples then I think this medium is actually really good because it means you get very broad exposure. It means that you rarely get stuck. So you don’t get that frustration that you have to overcome because the other person is experiencing the frustration and showing you how to get over it. Um, and not to mention you get to observe a practi practitioner of the language use the tools and use the language in the way it was intended rather than you playing around and not really knowing what you’re aiming for. And so I think I do actually think that for someone who is even like an intermediate programmer from another language, watching someone use the language is a great way to to like bootstrap and boost your own learning. But I think from there from the initial like let’s say the first three four five hours of watching someone program then I would think probably branch depending on what their preference was. Um like I think pair programming for those first five hours even if it’s not a live stream right but pair programming with them and then after five uh after five hours being like do you want to be in the driver’s seat now or do you want to continue this and see you know how the decisions we made early on turn into implications now or see you know how do we go from now we have an early implementation how do we polish it how do we test it how do we use the tools what llinters are available all of that stuff like do you want to observe or do you want to now get your fingers dirty because that’s where I think people will diverge in their in their preferences and in their means of their their preferences for learning. How about but I do think that that that early the the early few hours I think watching someone else do it is is really really useful. How about for very beginning programmers? Let’s let’s uh imagine somebody has not coded before. Is Rust a good first language to learn? If so, what would you cover or what would you focus on? Or if not, what would you recommend a complete newcomer learn as a programming language? So, I think it depends on what they want to build, like what kinds of things they want to build, right? If if what they want to build is like uh like browser games for example or honestly even like AAA games, it’s not clear to me I would start with Rust. If they’re aiming to build like scientific programming and like data analytics, not clear I would start with Rust. If they’re aiming to do um if they’re aiming to do like uh physics simulation for example, not clear I would start with Rust. Um so so there are some categories where I would point them at other languages instead. Um I think for the remaining categories, Rust is harder to learn is in my opinion at least harder to learn for people who know other languages because there are a bunch of things you need to unlearn that just don’t work in Rust that way. Whereas, if you’re new to programming and you’re taught about you’re never taught about pointers, you’re taught about references and the rules around them from the beginning, you would never assume that you could do these things with pointers because that’s insane. Why would the language let you do that? That’s crazy, right? So, so I think those safety rails don’t feel like safety rails. They just feel like what programming is like common sense. And so, in Yeah, common sense. It’s like, yeah, it lets me do the things I want to do and I have to follow the rules, but that’s how programming works if you don’t know how programming works, right? Um, and I think it teaches you some some healthy discipline that you can then go on to use in other languages later. So, you know, my my my sense here is um is that Rust is actually a pretty decent starting language, assuming you want to go on to do programming where the lessons that Rust teaches you are relevant. What are some um it’s a it’s a very broad question but given what we’ve discussed I wanted to ask about um advice for other programmers and if there are any core ideas or core principles that are burned so hard in your brain that you cannot live without now as a programmer that you think every other programmer should know. I I’m I’m sure there are I’m sure there are many, but but pulling them to the forefront of my mind is hard, right? Because many of these things are almost subconscious by this point. Um I think one thing that I’ve um really taken to heart in programming is that comments are more important than the code. Um, and this is sort of the opposite, I think, of how many programmers think about comments is that the comments are like the comments go out of date, they’re stale, they’re not that relevant. Like, you know, if they’re written, they’re probably useless. Um, and you see this even in in simple things like the default color schemes for syntax highlighting, comments are gray. They’re like partially hidden. So in my color scheme, I’m using a standard color scheme except that comments are bright orange. They are the most clearly indicated thing on my screen. Fascinating. And and and I do this because I want to a force myself to read them, but b force myself to if I’m going to write a comment, it better be useful because it’s going to be in my face all the time, right? Um not to mention it forces me to actually read over them so that I can correct them if they’re wrong. But the reason I’ve done this is because the number of times I’ve been saved, even if looking back at my own code and being like, “Oh, that’s why I did this.” Or, “Oh, that’s why I didn’t do this thing that I was about to do again.” Um, I think is it it’s it’s lifesaving and it’s a great onboarding tool for other programmers. It’s a way to keep institutional knowledge so that it doesn’t just remain in your brain and then when you leave the company or you leave the project or you eventually you know pass on then your your knowledge does not go with you. It stays in the code. Um and I I wish more programmers were diligent about this. Um, I also think that programmers are taught to write poor comments and there are very few resources on how to write them well. And that makes me sad because I think they can be such a good tool when they are used well. Um and you know the the best indication I can use here is um there’s this concept of literate programming which is to write code as though it’s kind of pros like you should read almost like English pros in an essay. Um and that’s partially about how you structure your code. Like if you have lots of functions like a very sprawling call graph it’s harder to follow. like actually have longer functions but where the sequential steps are easy to follow without lots of like divergence where you have to jump to other parts of the file. But the other part of and the other part of literal programming of course is naming variables and functions and everything. But apart from that it’s also about the comments that become the glue between the instructions. It is think of it as like the the binding words of English sentences where you need stuff to go between the words so that the the implication from one line to the other makes sense. And that’s how I think about comments in my programming. They are the the guide for reading the code. So they are not the code. The code is itself. It stands for its own like on its own. Um and you should not have the comments repeat the code just like you would not repeat a sentence in English with just different words. But you do need to explain what you’re trying to do, where you’re going, and why. And in some cases, sort of fill in the gaps. Like explain why there’s not code to do this thing because something needs to say it. And it’s not going to be the code because the code isn’t going to be in there. So, there better be a comment explaining I didn’t I don’t know do a do an insert here into this map or into the cache because uh how do you keep I think that is like certainly one of the the things where I I do something that maybe many other programmers don’t do at least that’s been my experience. I’ve certainly not been taught to write a lot of comments and especially when uh you are incentivized to produce code that produces output or when you are considered as a um code producing asset or resource code uh code comments are to put it mildly an afterthought. What are some principles? I think that’s sadly true. Yeah. What are some principles that you’ve followed that made writing comments easy for you? So, I mean, thinking of habits as uh things that are easy uh and let’s say at least mildly pleasant. How did you make writing comments easy for you, mildly pleasant at least? And what are some ideas that you’ve followed while writing comments so that the comments are explicative and stayed relevant so that they don’t go out of date and whatnot? Um I I think I think part of the answer for why I don’t mind writing them is is related to why I do 10-hour live streams and why I write a book about Rust, right? Right? It’s like there’s there’s an educational aspect to it where I enjoy trying to explain why the code is the way it is. Um because it feels like teaching, right? It feels like writing a mini book. Um and and I mean this is you’ll see this if you ever look at some of the comments, right? Especially in like my PhD code where some of it was like it was very subtle why the code had to do certain things that it did or or why it worked. And so there are some code comments that are like a solid like 200line comment. It’s like three or four paragraphs of text that end with a hence to do. Like it’s not even explaining a line of code. It’s like here’s a problem that this code doesn’t solve for this reason but it probably should but it can’t right now because to do and that’s something where where else would that insight that I had at the time of writing that comment have gone right so I had the insight of like this code doesn’t support this feature it needs to it can’t it’s hard but it’s okay for now right like that is a pretty complex set of insights about the code and about the absence of code in there that realistically I would have forgotten like two weeks later. I would have forgotten at least some of those nuances. Um, and god forbid someone else comes to look at that code like two or three years down the line and they try to add that feature or understand why something doesn’t break. Where else does it go? And I think that motivation is what drives me to write these comments is I don’t want my my hard-earned insights to go to waste. I think that’s a shame because uh code is a lot of thought, right? It’s not about the code as that up in the file, right? So where does the other code the other thought go? the thought about what you what you wanted to produce or what the application was supposed to do that you didn’t finish yet or the as you said the insights some I mean [snorts] when people think about I mean people will write things like ADRs for example or RFC’s right to write documents to sit next to the code that explain architectural decisions yeah but they’re separate documents right so separate documents and they’re like much more elaborate and they’re not as tied to this line of code. Yeah, this is uh this is fascinating to me because the way that I personally dump my my own brain, my own thoughts are various devices and by devices I mean paper or uh a document or something else that is not in the code itself. But now that you’ve described a good comment as adjacent to the thing that they’re related to, that makes perfect sense. like where else would you put it and where right and I mean in fact one of the ways that I end up writing these is sometimes I’ll write a function and I’ll write the function signature this works especially well in rust because you can write the function signature with like all the types and everything right and then I will start a comment inside the function and I will just start writing what the function should do and why. So I end up with like let’s say two paragraphs of text of like what this thing should do this not for trivial functions of course but like for anything that’s like I I have to put an algorithm in here right and I write things like invariance it must uphold things it probably needs to check that kind of stuff and then after I’ve written that I will start replacing parts of that comment with code not add in between the lines but replace the parts of the comment that are now code with code but after you’re done with that there will be some parts of the comment that are left that are now dispersed across the code you’ve written and those explain the glue in between the why the why does it need to check that the cache thing is like not set with this bit here why is that important what could break if it doesn’t uh do you do that that in your streams and um to gain clarity about what you’re about to write how does that process go for you while you’re working on a on an intense problem while live streaming specifically. I’m interested and maybe we can segue directly to that. Um, comments are a good way to structure your thinking, dump your brain and get clarity along the way. That’s what good writing is, right? This is why people journal all the time. This is why people write various kinds of documents and articles and books to gain clarity over an idea that’s been sitting on their on on their minds. Now while you are doing a long stream working on a hard problem um when you hit a stumbling block and when you get stuck on something um how do comments fit in the picture and what other tools do you use to get unstuck and also um maintain uh the engagement of the audience because the streams are long um there is only so much time and attention that uh a person has and [laughter] uh I’m wondering I’ve had people go to bed at the beginning of a stream and wake up and see that I’m still streaming. So yeah, they can be long. How do you do that? I’m I’m I’m curious. So I actually think in my streams I write probably significantly fewer comments than I do when I program for myself. And and I think that is because and I mean maybe arguably this is a problem but it’s because I articulate my thoughts out loud. That’s how a stream works is right. I need to actually say the things that I’m thinking otherwise the audience is going to pick up on them. But by doing so I feel that I’ve put the information out there and therefore I don’t need to write it down. And that’s arguably a mistake because whoever looks at the code later is not going to watch the stream. They’re going to only see the code. So maybe this is a thing I actually need to fix. Um but but I do think the things that I speak out loud during a stream are approximately equivalent to what I would have written as comments in the code. Uh the the two map fairly closely to each other. Um there’s a little bit more discussion that happens in the the live stream commentary because people reply to me and I reply to them. Then I I wouldn’t quite have the same sort of Socratic style interaction with myself in comments. Although that could be a fun way to write comments maybe. Actually, that’s a really interesting way to write comments. This like Socratic style of asking yourself questions. Um but but uh when I do get stuck, I think I think there’s a combination here of um the audience tends to find it interesting to debug the problem with me, right? So, so even though I’m stuck, I don’t think the audience is like sitting there twiddling their thumbs waiting for me to get unstuck and they’re bored until I get unstuck. Quite to the contrary, I think the the journey of I got stuck on something. What process do I go through to get myself unstuck? That is a big part of the interest in the video. That’s what they want to learn. Um, and so even if that takes me two hours, those are interesting two hours because all the things that I do to try to get myself unstuck are themselves tools that the audience can learn from and use themselves. So it’s pretty rare where I run into a situation where, you know, I think the audience is getting bored because of lack of forward progress on the objective of the stream. In a way, the objective is somewhat irrelevant. Right. It’s like journey before destination kind of thing. They want to sit with you and see how you get unstuck. Yeah. And I And I mean the reality is if if I sit at work, I can easily get stuck on a problem for two hours and then what do you do? Well, you’ll do a mix of head hit your head against it really hard, try a bunch of different things, run it over and over and see that the result is still the same and go, what is going on? You’ll have some outbursts of desperation. you might like do something else for a while. I’ll do that on stream, too. Um, but it’s like the combination of these techniques and seeing, you know, which things do I try when I decide to try different things. What tools in my toolbox do I pull out? Like maybe I’ll um run through it with GDB and step through it. Maybe I’ll add a bunch of print statements so I get a giant log that I can then run like I write a little Pearl script to analyze the log and then maybe that gives me an insight. Or maybe it gives me nothing at all. But seeing these tools that I use and how I use them is part of the useful aspect of the experience. Um, and I don’t think they mind that we haven’t actually made progress on the problem. And you’ve ga gathered the audience for that. I mean, you’ve positioned yourself as the kind of programmer that produces this kind of learning experience by seeing a live problem hitting your face and making progress or not in a certain amount of time and people just come to you for that particular experience. Selecting audience, right? Like there are bunch of people for whom this is not the way to learn and that’s okay. And I mean even even within my audience I have a I have I have a split right? So I have I have the the imple streams that are these implementation streams that are often you know many many hours and then I have what’s called crust of rust which are much more targeted. So they’re basically here’s a somewhat complicated feature of the Rust language. Let’s talk about it in depth. And it will be those are between an hour and two hours. So they’re still decently long, but they are very focused on one thing and they’re not really I’m not going to get stuck in those because I’m explaining a concept in great detail. And similarly, I have these um streams called decrusted where I take a like a well-known Rust library from the ecosystem and I walk through its API, how you use it, also how it works under the hood. And those two I don’t really get stuck in because I’m not writing code. I’m mostly reading and explaining. And those also are usually on the shorter side. Um, and so there’s some part of my audience that only watches those and some that mainly watch the implementation ones. Um, so even there there’s a split. If you were uh if Rust didn’t exist or uh if you had the time to write or look into any other interesting programming language that you find, I don’t know, intriguing or intellectually stimulating. Do you is does any other language come to mind? Yeah, I I I’ve I’ve really enjoyed exploring programming language up up through the years. I mean, that’s why I started fiddling with Rust was because I was like, “Oo, new language. Let’s try it.” Um, but interestingly, I’ve done a lot less of that since I started using Rust. And part of it is because it feels a little bit like home. Um, and I haven’t felt a need for another language very much. I think part of the reason for that search was I didn’t feel like I had the a language that really spoke to me. And I think Rust did um you know I really like things like being able to express constraints and invariance using types is like a a thing I want from a language and didn’t really feel satisfied with in basically any language I’d used up to that point. I tried to use Haskell but I found it too indirect maybe. I I like a little more control over what happens. I like a little bit less handholding. I mean, Haskell is handled in a very particular way, right? In the in the sense that it um uh it forces you to do something in a in a specific way and if you do it that way, everything is fine. But there’s like it’s the Haskell way or the highway and that was too much like that for me. Um and and uh and yeah, Rust sort of hit a lot of the buttons for me and so that reduced I think my curiosity for trying other things. But if I had to, I mean, I think there are some languages I’m intrigued by like um uh Daphne for example and and related languages like now rock um far like the formal verification languages which lean even more in the direction of everything is typed, everything is checked. Those intrigue me for sure. Um I also have some interest in languages that are um you know specifically for certain use cases like Zigg for example I think is interesting if you’re specifically trying to write something where in Rust everything would have been unsafe and so therefore you might as well have a language that doesn’t have anything that isn’t unsafe but it’s really good at unsafe which is sort of the niche Zig is trying to fit into. Um, I also really like R, but I really like R only for statistics and plotting, and that’s the only thing I use it for. But for that, I like it really like quite a lot. Um, so, so there are some languages I’d probably explore those a little bit more. And then I think there’s some there’s some very odd languages as well, like I’d probably do a little bit of playing around with D maybe or like TA+ is also a language I’d want to explore. It’s like whether it’s a language or or just a DSL for formal specifications is under debate. Um but like you know there are a bunch of languages I’d fiddle with. Okamel is another one where you know I I think I could like Okamel. I haven’t tried Okamel but it it feels like something that would like tickle a part of my brain somehow. Lean is uh interesting as well with uh the form of verification. Uh yep. Yeah. Um, Johnny, we are uh coming up on time and I want to be respectful of your time. Uh, I wanted to ask if you have any sort of recommended reading for uh programmers in general that you think most if not everybody should know it. Not necessarily Rust specifically and uh not necessarily uh I mean your own book is great. Um, I was going to say there’s this book called Rust for Restations that I’ve heard is really good and we’re going to uh leave a link in the description of the video of course. Uh, do you have any sort of timeless programming book that you uh that you think would still be relevant? Yeah, I I think there are a couple. So, so um, The Art of Unix programming I really liked. Um it’s sort of a you know this is how to think about how to decompose programs. Um especially in the sort of Unix style of programs that compose well with each other. Um it’s not too long either. Um there’s another one called the pragmatic programmer. Um where is it? Pragmatic programming. Noatic programmer which is also really good but it’s also very well known. Like it’s probably the book that most people recommend I think if you ask them this question. Um, another one I liked that I read um quite a few years ago now was one called Seven Languages in Seven Weeks. Um, and it’s a a book that takes seven languages that have very different programming models. Like one is an object-oriented one, one’s an imperative one, and one is a functional one. One is like an IO programming like JavaScript or prototype programming. Uh, one is like there’s a language called IO that is like also real weird. Um, but it it goes through some pretty odd languages and then tries to tell you how they’re different and why. And that was a good understanding of just how different programming languages can be from each other. Um, there’s also um, uh, what’s it called? It’s called the the FreeBSD operating system. The design of the FreeBSD operating system. It’s a it’s a book that explains u the entire structure of the FreeBSD kernel. Uh everywhere from like how it does to virtual memory allocation to disk access to IIO devices to power on and power off all of those things. And even like it’s not quite how Linux works. And it’s it’s I don’t think it’s been updated for like the latest BSE and everything, but it’s an it’s a really cool dive into like these are all these subsystems that it’s like now you have a sense of roughly what they do and how they work and even though they’re slightly different in other operating systems, the concepts still apply. Um, and it it teaches you something about, you know, the the the machines that we build on top of. I think lessons in operating systems in that sense is like worthwhile to to learn. Um and then there’s another one that isn’t really about programming but but it is a very useful tool um which is one called oh the the visual display of quantitative information or something uh by Edward Tuft. Um, let me see. I think I have it here. Visual display of Yeah. The visual display of quantitative information. Wow. Um, and it’s by Edward Tuft and it’s basically a book about how to plot data. And why was that interesting? Why why is that relevant for programmers? Ah so because very often if you’re trying to debug something and and usually this is like performance related things but even if it’s just like the system is behaving weirdly then you collect a bunch of data and then you look at it in your terminal but realistically humans are much better at spotting patterns in visual representation of data than in textual representations and so you might throw them into like you know um ggplot if you’re using R or Mattplot lib or like new plot or something. But if you don’t choose the right axes, if you don’t choose the right things to plot against others, if you don’t choose the right visual representation, you’re going to lose out on some of those patterns. And what this book is really good at is trying to teach you how should you think about visualizing your data depending on the information you’re trying to extract or if you’re trying to present it to other people, the information you’re trying to convey. And it gives you way more tools for representing that data visually. It gives you in a way it teaches you a richer visual language for data representation that then makes it easier for you to understand your own data and present it to others in a way that will like tell you about properties of your system you didn’t know that you can then use to debug, make them faster, uh or just make other people understand how they work better. I have taken notes. Thank you so much for all of these, John. And uh thank you so much for making the time. It was a pleasure to have you. And uh no, thanks for having me. This was fun. Yeah, it was more fun for me, promise. And uh [laughter] yeah, and uh for everybody listening, uh we’re going to leave links to John’s website and John’s book, Rust for Stations. Uh John, is there anything that you would like to say to my audience, which is mostly Scola developers? before we wrap up this conversation. Um, you know, I I think one of the things that drew people to Scola was this idea of you have Java but with uh better ergonomics and more types. And let me let me tell you what has better ergonomics and more types. There’s this language called Rust that uh that that might scratch similar itches uh but the integration with the JVM is not going to be as good. So that’s your that’s your big downside. Um but but no on a more serious note I think um uh I think if you’re a Scola developer trying [snorts] to force yourself to use Rust for something and seeing if you can get a little bit of that um borrow checker built into your head, it will help you write better Scola as well. And it’s not just the borrow checker, it’s also giving you a sort of somewhat principled approach to learning about the the aspects of type theory. that Rust forces you to learn that again you can leverage in Scola territory around using types to enforce correctness in more of your programs. Like I do think there are actually useful learnings for you to bring back into your Scola world um by just getting some exposure therapy to Rust even if you don’t end up actually using it for production or or using it in the long term. This is something that I’ve noticed good languages do. they make you a better programmer even if you don’t use said languages and Scola has been for uh that way for me and I’m sure Rust is the same for many people. Um John it’s been a pleasure. Thank you so much for making that time and for everybody listening thank you so much for watching.