mergeconflict278 === [00:00:00] James: Frank, before we get into today's topic that is so hot and spicy hottest ever in the world. But before we get into that, I have a question. I got a question for me that was asked to me on Twitter. And I want to ask you Frank, because you and I are in the same boat because you and I both bought a laptop this year. Um, of interest. And this is the question you ready for it, Frank? [00:00:32] Frank: Oh, I I'm nervous, but sure. Yeah. Random question hit me [00:00:36] James: and James, you both bought a brand new M one Mac book air this year with Apple's recent announcements. And on your podcast last week, talking about the brand new M one pros and M one maxes. Do you feel that you've made a grave mistake and wish that you could go back in time and remove it from the. [00:00:58] Frank: Yeah. Nope. Nope. Uh, I I'm answering for myself here, but I'll also answer for you, James. No, you do not feel any remorse or anything like that. It looks the, the F1 pro it's gorgeous. It's no problem. And the min max, the min max max they're there even better. No doubt there. And yes, I probably the thing. If I have any regret or remorse or anything, it's about the fact that it has more ports than my little computer. Um, the power increase. That's good. I was complaining about Twitch and everything, but it's not that bad. Like Twitch was the only thing killing the poor computer everywhere else. That's been fine. So no, no huge remorse, but, but in two or three years, Two years. Well, we'll see mark. My words. I will be getting one eventually, but no, I don't have that much remorse. [00:01:55] James: Okay. Yeah. I I'm. I'm there with you. I have no remorse over this purse purchase and acquisition. I'm very happy with my MacBook air. I really enjoy it as like my main laptop that I carry around. Now realize that 99% of my time, I'm actually developing on a windows, desktop rig, then super crazy powerful. And you yourself are on an iMac pro, correct? [00:02:19] Frank: Yeah, that, that's my main where I sit my butt all [00:02:23] James: day. Yes. And, and that's why it's okay. Because my main rig that's with me, the majority of the time is not the Mac book air. Right. And if it was, I think that that would have been that if I was replacing a. 15 or 26 MacBook pro with a Mac book air then? Yeah, I might've been like, oh, but I don't think I would have done that, uh, in general. Right. And, and the thing that we really want, the thing that you probably really want is an iMac pro with an M one max chip in it. That's all specked out because to me. This is my on the go device that I want. Nice. And with me all the time, I agree on the ports. Um, I do think we got bamboozled on the ports. Um, a little bit, they're bringing back the ports. They could have just brought them back, like, you know, five seconds earlier. But beyond that, I am happy, but I am with you. I think that my Mac book air because of the price. And of course the discounting quotes that we got, which is really not a discount. Cause we paid out for $500 and they give us $500 back. You know, if we gave them more money than $500. I do think that it won't last. As long as my Mac book pro my 2013 day cause I was using that almost full-time for five or six years, and then it was just kind of, you know, done for, so I do think that, Hey, in a two years from now three years from now, am I going to be trading this Mac book air in for whatever the new Mac book pro is or new Mac book air that has a pro on it? Probably I think. [00:03:53] Frank: Yeah. Uh, yeah, you nailed that. I wasn't even thinking about that. Yeah. The reason I don't mind so much it's cause it's not my main dev machine. Not to repeat everything you just said, but I've been lucky that I'm able to sit down in front of a computer all day. Um, I think if I were. I don't know why I wasn't even gone for a month away from my big iMac and still the air was fine. So if you have one, I think you're fine. If you don't have one, then now's just a good time to upgrade, upgrade to the pro. [00:04:25] James: Yeah. And if you, if you don't have the money for the pro, because they are expensive, do you wait, do you wait for next year's MacBook air? If there is one. Oh, [00:04:37] Frank: no. Um, I think there's going to be, they'll probably do an update, but it's not going to get like an M on max chip in the air or anything like that. Not that I'm anticipating. I mean, there used to be those EHRs out there. They were actually pretty powerful machines. So apple does have a history of putting a big processor in the air, but I just don't see that happening next year, maybe in two years or something like that, but, uh, not, not for a little bit. Yeah. Uh, now when the M one max iMac comes out, oh boy, oh boy, I don't, my wallet's not quite ready for it. I already, when did I get this thing? 2017 ish. Like the beginning of the year, I said I was going to get five years out of it. So please apple. It gives me a whole nother year before I have to spend a lot of money again. [00:05:23] James: Do they even a deep and Sally iMac pro I don't even see. [00:05:27] Frank: They better know you, they might, that might be off the list. Yeah, I think, yeah. We're all waiting for it to turn into an M one iMac pro. Oh, that's right. I forgot that that came off the list. I only got like one rev update. Yeah. I think crazy too. But I think only one rev is weird. It's a good machine though. So whatever, I, it's still more power than I use every day. Yeah. [00:05:54] James: And I do think like, you know, it, it's a good, uh, time to think about if you were going to put this machine together, is it going to be my next five-year machine? And what's the price worth for you? Where I think when I went into the MacBook air starting at a thousand dollars, I'm like, okay, this is my next two to three year machine. And that makes sense to me. I did, I did update it though a little bit. I did get [00:06:14] Frank: the. Yeah, I know. Cause I was going to say like, it starts at a thousand, but I paid around 1700, I believe from mine. And the pro starts at two grand. So you're, you're just at two grand to start. Plus we wanted that max upgrade. So what was that? Two or 400 more dollars? There is quite a substantial price difference if that was my only main machine. I can a hundred percent justify, uh, that, that price in that power. But if it's not, Nope, it's just going to be a little portable computer that honestly collects a bit of dust on the shelf. Yeah. [00:06:51] James: All right. Cool. Let's get into our topic this week. The hottest of hot, the spicy of spicy, the hot reload of the hot reload. You Frank are doing a deep dive on your Twitch stream or recently diving into the hot bits of hot reload. And, uh, you said you wanted to talk about the inner workings of hot reload for.net. Is that correct? [00:07:12] Frank: Yeah. Yeah, it's, it's a little bit of new knowledge for me, but as you know, I have been interested in hot reload by other names for a long time. We used to call it live coding, and I used to call it patching and hot patching and whatever. I'm just getting tired of the development loop. And I just want to update my code much faster. And I've written all sorts of solutions over the years. Um, if in fact, like I went a terrible deep dive into.net many years ago when I tried to write my first interpreter for, to achieve this. And then later, um, I developed like the continuous IDE add in, then I developed continue. My IDE for the iPad. Uh, I've been in this space forever, but it never occurred to me to figure out how, how does Microsoft do it? How does the runtime actually do it? How does mano do it? How does dotnet core.net six? Do it? And so on my Twitch stream, yeah, I just dove in. I said, look, I want to learn how I want to learn how the patching stuff works. And what I found was quite interesting. I found out that. Public this ability for the runtime to change the code is a public feature of the runtime it's it's in docs.microsoft.com. You can go read about it. Uh, the problem is the docs. Aren't very good. So a long journey of hacking and sued, and I thought it'd be a fun topic to talk about. Well, [00:08:40] James: let's talk about that a little bit, because you were saying that you over the years have built many things and you, and I've worked on many things together as well in this space. I'm. Bye. Bye. By work together. You did all the work and I didn't do anything. Um, but, um, you know, let's talk about specifically the differences here, because you said that there was an interpreter that you had, you had previously, and then you still have like continuous and other things like that. And then there's this patching. So however, these fundamentally different. And what are the, what are the re the side effects of how each of those work? You know what I mean? Like there's gotta be limitations to different limitations of each and interpreter versus a patching mechanisms. [00:09:26] Frank: Yeah. Uh, we can even put the interpreter on the side for the moment and start with a quick reminder on how.network works, the magic of.net. So we get cross platform code. Uh, execution by a magic trick of not having our code actually be machine specific. It is IO code. I think we're all pretty familiar with that. So our dot DLLs, although they look like windows things, they are not, in fact windows things. They just have a bunch of IML code in them. And a very important thing called the metadata, which is, uh, all the classes. All of the fields for classes, all the methods for classes, all the properties, how they relate to each other, all that complicated stuff, uh, is there in.net. So that is roughly called the metadata. And then the code that you actually execute, that's called the I out. Where does all this work well in a hot patching system, what you want to do is you have this program running and you want to make a change. I want to change how a method works or something like that. And so what I need to do is communicate to the runtime that, that I L has changed. Now that's easy. Communicating is easy. The hard part is the runtime has to actually implement that change. And that is a tricky thing. Because well going all the way back, whenever a method executes, we have a jet, we have to turn it into machine code at some point. So there is a process out there that, uh, can convert from IRL to machine code, and then start executing that machine code, whether that is a jet or an interpreter almost doesn't matter. What's important is that we give it new ill and signal to the runtime that the aisle has. [00:11:23] James: Okay. Okay. So, so there's code in your editor is you compile it and then you compile that into IO and the intermediate language. And then there's a CLR common language runtime, right. That is able to run. So whether you're creating C sharp F sharp, VB, all those down into. I L and then the CLR common language runtime is able to run that code that I L sorry, that I L with the metadata. And then in this case, in most cases, it jets just in times, compiles that I L into machine code based on where it's running or in the case of iOS. It's ahead of time, compiled, um, as well. Uh, so I managing some, some different things there. Uh, but however, on the emulator and simulator they're jaded. So we'll just say, we'll just leave with a G here cause you're in debug mode, right? Is that the correct stack that I just described? How dotnet works? Cause that's pretty different. A lot of other programming languages and environments out there. [00:12:25] Frank: Yeah. Yeah. It's what makes it special. It's what got me interested in, into the, um, CLR in the first place. So the important abstraction is you're correct. The language does not matter because all, all.net compilers, no matter the language Python, C-sharp F sharp, they all compile into this aisle and this metadata, this managed metadata. Hm. That that's the common part of the common language runtime. The runtime par is it takes that metadata and has to figure out how to execute it on the machine. The AOT, uh, let's kind, kinda ignore it for the moment, but what that does is it acts more like a traditional compiler where. Does that first step of converting everything to ill, but then converts it to machine code, uh, uh, before you run it ahead of time, I have time. Yeah. So, you know, what I described is actually a pretty simple process, right? Why don't more programming languages do that. You know, if there's a method out there and there's a method body, then you know, just go change it. Well, the reason you can't do that, C is because people who call that method have to have a pointer to that method. And they make very specific, uh, assumptions about that. So if I ever want to change that method, I can't just go and override it because there might be a version of it executing right now, you get into all sorts of terrible race conditions. So what you have to do is tell every function that's calling that method, that there's a new updated version of it. And that's just a mess, you know, no one makes good hot patching systems for native code. It's it's just too terrible. It's too fragile. Who knows what's going to happen, but in a managed runtime, it's technically possible because the garbage collector knows what objects are out there. The runtime is able to stop execution if it absolutely needs to. I mean, ideally it wouldn't stop execution, but it can be smarter about saying, okay, so you want to replace the IFL and this method, that's fine. But, um, I've already jaded it. I've already converted it to machine code. So now the runtime. Unconverted from machine coder, realistically, just throw away the machine code and say, ah, there's a fresh IO version of this. We have to reach it this method. So, you know, you can think of it from a very 10,000 foot point of view. It's a pretty simple process, but things get more complicated of course. [00:14:55] James: Well, because what you described right is that there was already a method and there's contents inside that method that you'd want to update. Right. So, so I'm assuming that also. When this thing happened, I have no idea how anything works. I'm just a developer people. I don't know how anything works. Um, high high-level developer here, I should say, I don't know how anything works. And, but there's, there's probably a lot of different entries into, let's say a big, let's say there's a big table. Let's say, you know, that, that stores all the things in an application, right? There's uh, there's there's classes, there's properties, there's methods that are on there. There's um, using right. [00:15:37] Frank: This is hilarious because I don't know if you were just joking around or not, but the metadata, the IOL code is actually stored in tables. Literally they're called tables and it has like a database kind of schema to it. There are IDs referencing everything. So I just want to give you points. If you didn't know that the metadata, your assemblies actually are tables. They are like a tiny little frozen database. So I just want to interrupt and say good job. The big [00:16:02] James: V table, if you will. So, um, [00:16:05] Frank: uh, [00:16:07] James: yes, well, I, okay. I only really know about tables and how things are stored only because of inheritance and abstract in virtual classes and how things work. That was my data structures class. I'm pretty sure my, my instructor, Phil Miller taught me about tables and stuff like that. I forget now, but I do know that there's tables in there, Frank, like you said, so there's there's tables and all things are in the table, so that's good. Yes. Cause I'm glad, I'm glad that that, that I was, that was accurate there. So that's. Yeah. Uh, okay. So they're all in there. And in this instance of, of throwing away the budgeted code, it is it, is it different for every single one of those things that are in the table? And like what happens when you just add new methods and call it from an existing method? Like, does that cascade as our cascading. Not to reach [00:16:55] Frank: it, ocher ocher. So, uh, let's call what I just said, that method, body replacement as code swapping 1 0 1 table stakes. Like you have to make that work, but consider all the other things you can do to your code. So. Delete the method. Well, okay. That, that doesn't count because then the things that called it won't work. So you'll get a compilation errors, so we can't patch it, et cetera, et cetera. So that's fine. We can ignore deleting a method, but, um, what about adding a field to an object? That changes the memory structure of every object. So let's say I want to patch the runtime and say, add field to the class string. Now, every string in your app. And there are a lot of them has to add a field. I don't think you can actually patch string every one. So don't try. But, uh, imagine that for any other like common object that you have in your program and you add a field to it. Now, the runtime has to like stop the garbage collector and be like, yo garbage collector, everything has changed. So every object with this, um, uh, type or this class type go out there and rearrange its memory to make room for this. You know, that's, that's tricky business. And then not only that, but, um, obviously any new method that references that field, you have to go, uh, J all those, but that, that kind of takes up a space and the. You changed a method kind of thing, but yeah, it's a simple thing. Like adding a field can do that. Deleting a field. Obviously you would have to stop the whole thing because no method that could ever reference that field. But now the big cascading ones are you add a whole new class. Cause that's adding fields, adding methods, all that kind of stuff. [00:18:44] James: So does that stuff work? [00:18:48] Frank: Miraculously? Okay. So, uh, the, that, that first level that I was describing, kind of swapping out method bodies that was. Well, maybe like 2013 edit and continue was added to visual studio. I don't remember my timeframe very much. Um, but really roughly around them. Uh, we got that ability, but I think anyone who used it always ran into the frustrations of there were certain code changes that you would make that would just not work and imagine something like link queries or, um, async programming. They asked. Create types in order to make a sync await work. And in order to make link work, you have to generate, uh, callbacks and Lambda functions and all that async creates a whole state machine. And that requires creating. S and methods on those types and generics and you know, all sorts of crazy stuff. And so there were just operations you couldn't make too, um, method changes because they would end up creating other types out there. So that's your terrible cascading problem. That used to [00:19:58] James: exist. Yeah. And I remember editing continue and it was a weird name because you'd have to like add a break point and then you would try to change something. And I was like, no. And then you have to stop your whole application. It was like, it just, you, oh, you're like, oh, I referenced this thing, but I got to bring in a namespace. I was like, that's not supported. And cause it's not in the method. Right. And I think the only thing you could really do is be like, okay, count plus plus equals now count plus equals two. And then, then you would continue. Ideally. You know, in the scenario we're developing, I don't necessarily want to always have to add a break point to like, change my code and do stuff that doesn't make a lot of sense, especially when we were talking about like XAML hot reload, which were, I'm assuming completely different than actually just like the code part of it, uh, in general. What I learned from XAML hot reload, which is that I want to be able to change all my stuff at all the time. And I want this and that. And, you know, I want my state to remain and I want all this other stuff. There's a lot of implications there of just, uh, a Dom stack, uh, in general. But, uh, yeah. So you want method, body method, body replacement, to total as the default right now, we're [00:21:06] Frank: talking about. Yeah. And you want that to simplify, like you were saying that, that holding of the state, the whole hotness and hot reload and all these kinds of things is that you can change the background color of a view without changing the text or something that someone has input into it. And that's the tricky part. So in past things that I've made, like XAML pre viewers and things like that, what I would do is take those animals string, have the runtime. Create all the objects for that. And then redisplay it on the screen. The problem is that loses all the state that was there. So what you can do instead is okay, go through that same process, take a SAML string, inflate, a bunch of objects, and then look at the difference between the two and copy, uh, properties and values over from the old view into the new view. But even that's. Kind of janky, you know, we, we got it working. It works. I try to do a little bit of that in my IDE on the iPad, but imagine if we don't actually recreate all the objects, we just modify the objects. That's so much better. And so XAML is actually a great case in this. It's a great way to compare and contrast because XAML has always had two modes the way of take a string and create a bunch of objects that's always been supported, but then we got XAML compilation and that was mostly a feature to make our apps faster at run at startup times so that they don't have to do a bunch of parsing. But, uh, the side effect of that, the benefit of that is, well, if XAML turns into. And we have this mechanism for updating code. Then we can use that same mechanism to update XAML. So it's kind of neat. This XAML preview used to be this kind of an easy trick. I used to do like a wee example all the time, because it was real easy to write as M auditor, but you would lose the state all the time now by combining XAML compilation and this feature for the runtime to patch itself, we can get much better, um, hotbed loads of XAML and previews and all that. [00:23:16] James: Got it. Yeah, that makes a lot of sense where it's not just, oh, here's this string reproduce it, throw everything away. It truly is. Almost a diffing, uh, in a way [00:23:28] Frank: it literally is a Def. So I, if you'd like, I'd like to talk about, uh, some of the details of the runtime, how this happens, because editing continue was always a visual studio feature. I never really had access to it. I'm a Mac programmer. I use mano just never really had it. But it turns out that, uh, even mano has had support for the feature is definitely called edit and continue copyright trademark registered in Microsoft. But it's, you know, the ability for the runtime to patch itself has been there for many years, even mono has supported some basic features of it and they've added more and more features. So. The problem has always come down to, it was never like a public interface. It was never actually available from the runtime. It was just the secret things that debuggers could magically do. That's all changing in dotnet six and there is in fact, a public method out there. It's on, uh, it's in, it's in a class called metadata updater, but I'm totally blanking on what namespace that is. It's system dot reflection. Metadata metadata. I don't know, search the docs it's out there. It's public. And there is a magical function on there called apply update. And if you give it and the supply update is kind of hilarious, it just takes a span of bites. Where do you get these bites? Who knows James, if you have these magical bites and you call this function, that runtime will just update itself. So I want to say that that's, that was kind of a regulatory. Thing there for me that there is now a public way for the runtime to modify its own code, uh, that any app can take advantage of. So use it wisely people, but it's, it's technically out there and it's technically public, so good luck. [00:25:17] James: So these magical bites, how did those yeah, no, to update who's up. Who's updating. I got, I guess, whatever the ID or the code editor. The Don at CLI like when you run your app, like how, how does it, what's doing the, the magical. [00:25:36] Frank: Those were all the questions I had. That was the deep dive I had on the twist. I had just discovered that function was like, who is, who are these bites? What are these bites? Why are these bites? And there's actually three sets of bites, three bite buffers. You pass it. Um, so there's a metadata. Delta Def Delta, same difference. There is the IRL diff Delta, and then there is the PDB, the debug information, because all this stuff we've talked about for 25 minutes in this whole episode, I never even mentioned, not only do you have to do all this patching of the actual methods and objects out there and all of the metadata. But there's that debug information, you know, people want to be able to edit and continue and have break points. So you have to do all that stuff. But fortunately, that debug information is optional. So let's ignore that. So where do these metrical bites come from? James? Where do all magical bites come from Rosslyn? Oh [00:26:34] James: yes. That, that, uh, the source, uh, magical bits that make a C sharpen all the language. [00:26:41] Frank: Yup. Yup. Yup. Uh, Roslyn is a visual visual, basic, and C sharp. Are there other Rosalind languages out there? So F sharp does not, uh, currently partake in the Roslyn, but Roslyn is capable of generating these deaths and what they are. It turns out those magical bytes. You're going to love this. They're in a sense. Just an assembly hanging out, hanging out, it's called a Delta assembly. And as the name applies, um, it's actually just, what's been added and what's been updated since the last patch. So it makes complete sense. If you think about your big C-sharp app with a hundred types in it, because you love creating classes, you got all that. You've ex you've compiled that code. It's running somewhere and it's great, but you've decided to change. Uh, you've decided, let's say add an interim. Between those. So what the C-sharp compiler does is very intelligently and it's complicated. We could talk honestly for about 10 hours about how the C sharp compiler actually does this, but it sees that all you've done is added in. So it creates a brand new assembly that contains just adeno makes sense. And then it turns out assembly into bites. No big deal there, no compression or anything, it's just there. And then you call that metadata update dot apply updates. That's all it is now. There's a lot more to it, but that's roughly it. So it's just a little assembly that contains just what's been added or modified in your. [00:28:23] James: Oh, okay. That makes some sense then. So it's hanging up and these are all, these are all just automagically generated. Well, how does it know to generate that? If, if you're in debug, you've already compiled. You're not really compiling though. [00:28:38] Frank: When you do. Yeah. Well, you know, you have a lot of options, so let's just say what it is. So just to repeat myself, what it is is a death, how you cook that diff is really up to you, how smart you are and all that kind of stuff. So in the case of Roslyn, what Roslyn does, is it actually. Well, it has a few different modes, but it has an analyzer that can take two different syntax trees and go through and figure out, oh, this, this was added, this was removed this et cetera. In the ideal case, you would not recompile the whole whole app, but in an unideal case, you can think of it in simplest terms of yes, you could just recompile the whole app and then just look at what was added and what was changed. But it turns out, you know, doing that kind of diff can be a little bit expensive. So Roslyn's much smarter about keeping track of it starts with one version of the assembly, then it knows. Okay. I patched it to add these types and then, oh, they made a third edit. Now they've modified this method. So I'll add that to the patch. Oh, now they've, um, I don't know, edit another type. We love adding types and it'll just keep adding that to the Def. And ideally it would only be recompiling. The parts that actually changed or actually were affected, but on ideally it could always just recompile the whole assembly and then, uh, figure out what changed from there. [00:30:05] James: Got it. So that's why I would, if I'm inside of. The vs. It knows what editor file I change or where I hit save on. Or if I'm doing done at watch it's as a file watcher that is watching the files and it's informing Roslyn that these things change and go create [00:30:22] Frank: this. Yeah, exactly. So Roslyn has on itself, a public method. So, uh, Roslyn, you, you create, um, a project from a project. You can create a compilation of that project, which has all the settings. It needs to actually, you know, compile the code. And then once you have a compilation, normally there is a method on it called dot emit, and that puts an assembly. That's the normal way you use Roslyn, create a project and a bunch of junk. Creative compilation have a compile by junk, I mean code obviously, and then obviously, and then you call document and an assembly pops out. It's great. Wonderful. You can even run it on the iPad. I love it. But there is an additional method called dot emit difference. And that it's a public method it's out there, everyone that is the magical method that will, um, create these, uh, Delta assemblies, these diff assemblies, these things that you can then feed to the runtime. So there's a lot of ways to go about it, but so I'm sorry. What you need is an assembly death. There's a million ways you can generate any way that you want. That runtime does not care. Roslyn has a way to do it in C sharp, um, by being very clever about edits and things like that, it can actually see, oh, okay. All they did was change a number like a function used to say return, hello world. Now it says return goodbye world. That's a very small change. It doesn't have to recompile the whole project to figure. But that's all available to us as a document difference. [00:32:02] James: So it's a really, what war, what we see is it's the code editor or CLI, or whatever's looking at the files to it, which already knows how to like bundle up this bundle of code to give it to Roslyn emit. The first thing, watch for changes, emit. The other thing, send that over to the runtime. And it can do that when it's debugging and not debugging. [00:32:32] Frank: Yeah. Uh, this used to be a debug, only feature, but it's been lit up both of the runtimes. I have to tell you, so this metadata updated out, apply updates it's off by default. It does not work by default. Um, probably security reasons. You know, lots of reasons you don't want to have people be able to maybe just be able to do that, but it doesn't, it does not require, uh, the D debugger. So there is a metadata update or.is supported function that you can call any time to find out if it's available. What you do is configure the runtimes to enable it. In the case of.net core.net six, whatever you want to call it, uh, there is an environment variable you can set and they face a mano. I think it's also an environment variable, but I forgot to look up which one it is, but both mono and dotnet six can do this. You turn that feature. But importantly, it's not going to do any communicating. Like you turn that feature on and nothing's going to happen. You can't like connect yes. Code to it or anything like that. You have to do all that plumbing of communicating, of talking to Roslyn of, um, actually executing the diff and all that kind of stuff. There's a lot of communication and hand wrangling and all that, which is taken care of, um, by IDs. So this is. Public stuff in the runtime, you know, the runtime supports patching itself. Uh, the Roslyn C-sharp compiler supports emitting differences, but those are your basic building blocks. You have to do all the communication and, you know, data management [00:34:11] James: yourself. Gotcha. And that's what S or the watches doing even done. I watched us doing the same thing then question mark. [00:34:20] Frank: Yeah. Um, I think dotnet watches using roughly the same code as vs. They have like slightly different interfaces into it. But I think that they're both roughly using the same technology. I don't hold me to that. There's nothing, you know, nothing public saying that that's how it has to be how it works, because like I said, the fundamental building blocks are there. It's just how you take advantage of them is really up to you and how you want to do your communications. The problem is that emit difference is a C-sharp feature. I think there's one for visual basic also, I'm not sure what its status is, but it's not something that you know, is just available for F sharp. So there's, you know, F sharp does not have edit and continue. And the reason it doesn't have edit continue because it doesn't have this sophisticated feature that Roslyn has, that's able to output these assembly deaths. I kind of want to go down a whole rabbit hole of how to, how do we make this work for F sharp, but I'll just lay it out. There's a couple of ways that could be done. So the F sharp compilers complexity would have to be increased a little bit to where when it's output. Um, an assembly. It has an old assembly to compare to and does the right thing only does patches and things like that, and then can emit that Delta assembly. So that would be a big change to say the F sharp compiler to make that work. Alternatively, uh, what we've been thinking about in the community is creating just a generic tool that gives you. Uh, current assembly and given a new assembly calculates that diff, and then you can just apply that to the runtime. So the downside of that is you're not taking advantage of language smarts and seeing that a minor change should create a minor compilation step, a minor change would still create a full compilation step. That benefit is you could stop. Patch a running app. So you would still preserve state and everything. The downside is you would still have to go through a whole compilation step, but it's neat that even the runtime is providing this building block. It's, it's up to us to figure out how to provide at the data. It needs to do the work. [00:36:25] James: So the question I have for you then is now that you know how it works and what methods are available or are you able to get this working in continuous? Did you build your own. Pipeline basically to make this work, or did you, did you get that far down the rabbit [00:36:41] Frank: hole? No, I did get that far down the rabbit hole, but I got far enough to realize, ah, I can't really use this for continuous, so there are a few issues in the way here. Number one. I don't really want people patching continuous as code while it's running. Not, not a great thing. It already kind of allows a little bit of that, but I don't love it. So there's no real benefit to allowing the IDE itself to be edited so that's not needed. But then the other big downside is probably none of this works in an AOT scenario, but I want to put a caveat on that, but let's look at the problem in an IOT scenario. All of our methods are compiled down to native code in the beginning. They do not. When, when a function calls another function, it doesn't talk to the runtime and say, Hey, can you go look up that function for me? I need it. Is native. It has a pointer to that function and it goes and executes that function. So there, it can't do the same trick that the jet can do. Or the, um, anytime a function is called in the jet, the runtime can hook itself in or poke around and change things up a little bit. And an IOT scenario. That runtime is not there. That's why IOT is so fast in San Fran. That's why I love AOT, but the downside is without a runtime. There's no way you can do a hot method swap. That's the reason I don't think I can use this for continuous. [00:38:12] James: Got it. Got it. [00:38:13] Frank: That makes sense. But, but caveat now, caveat, uh, if you're running under the interpreter, interpret. Absolutely can hot patch. The problem there is I have not in my research is found out if the mano interpreter supports any of this stuff, because this was. Pretty a highfalutin, a fancy feature that wasn't really needed slash used everywhere. So now that it's a more common feature now that it's coming in, dotnet six and we have these public APIs to, uh, we might see, uh, increases in functionality and things like that. But for the moment for today, right now, I don't think any of this stuff would work for an iOS app, maybe for an Android. Definitely for a windows app, but uh, not for iOS. [00:39:02] James: Yeah. Yeah. If you were going to try to bundle it into your application, but when you're developing the apps, they're all jetted, so it's [00:39:08] Frank: okay. Yeah, exactly. Yeah. Uh, it's still on-device though. I think you would still have to run under the interpreter or something because. Even on device, your, your, your, your compiled to native code, even when you're doing, even during development, even during debug. Now the simulator that can run the jet Mac apps, they can run the jet, all sorts of those scenarios. And who knows, maybe AOTO get it at some point in the future. Got [00:39:33] James: it. Got it. Now here's one class question for a year. So how did, how did, um, fabulous work for F sharp as you were talking about F sharp earlier and Don Syme and community, and people worked on this, you know, fabulous. Um, Fabulous fabulous library for F sharp to build cross-platform applications with F sharp and they had a. How [00:39:58] Frank: thing in it. Yeah. Yeah. Um, I can't say specifically how it works because I haven't read the source code, but I can probably rough out roughly how it worked, the biggest, best benefit of the L mesh architecture, the reactor architecture, the fabulous architecture is that all your data access is. Kind of centralized, um, has a first-class notion of this is the data of the app. This is the state of the app. And because the state of the app is known at all times and it's rooted roughly to one object. You can always see that. That object. So when we go to replace code, we don't have to do all this fancy looking around and figuring out what state needs to preserved and what state doesn't need to be preserved. There is roughly one object out there, serialize that puppy or whatever, keep it in memory. You don't even have to serialize it, leave it in memory. And. You know, spin up that new code and assign that one object over. And then because of the beauty of that architecture, once you assign that one object over the whole app lights up and restores its own state, because all the state is rooted at that one object. Fancy. I, the L mesh architecture is really cool. The fabulous architecture is really cool. I find it a little constraining when actually writing an app, but, um, for, for big complicated apps, but for form style apps and everything. It's cool. It's cool that the architecture, you know, this has nothing to do with runtimes. This has nothing to do with languages. The architecture supports that capability kind of got. [00:41:39] James: Got it. I want to give a timid Timothy, cause there's also the, the maintainer, the brand France. I want to make sure that him and the downtime get the, get the shout outs there and everyone else has worked on the project too. I don't want to just say that Tim has been on a few Xamarin shows and wrote some great blog posts on the Don ed blog and Xamarin blog about it as well. So very cool. That's interesting. Um, yeah, all sorts of these technology. We're all trying to see. We're all trying to achieve the same thing right at the end of the day is we're trying to. More productive code, faster, you know, stop, you know, having to have the compilation get in your way from tweaking code like that. That's our end goal at the end of the day. [00:42:20] Frank: Yeah. Yeah. I used to complain that the problems with dotnet were the speed of the compiler and then the loop that we all get stuck into, change the color, compile, run the app, close the app, change the color, that loop. We're all just trying to reduce that loop down to nothing. And I used to be jealous of the scripting languages out there because they could. They didn't have the compilation step because they're usually interpreted. And so they just light up really fast so that, uh, that loop would naturally be shorter. Well, now what's really cool is I have a compiled language with a full type system that can communicate with actually multiple kinds of languages. And the runtime itself now supports this feature where I can change actually running code. Like, uh, game development. This is going to be wonderful for game development, because just getting into that one scenario into a game for the deaf loop is really hard. Instead, you move yourself to the one scenario and then you change all the background colors to your heart's content. So now I feel like.net. We're getting the best of both worlds. We're getting. The speed of not having to go through that compile step anymore. We're getting the speed of not having to restore our own state manual anymore, which is something the scripting languages can't do. But we're also getting all that in a compiled language with a type system and all that kind of stuff. It's kind of awesome. And so congrats to all the runtime people in the compiler people for making this. Yeah, very cool. [00:43:50] James: I'm super excited about it. I've been using it for quite a while and just bits and pieces coming together. And man, Donna comp is like two days, like next week. It's like, well, this episode comes out on the first and then it's like on the ninth. Oh my gosh. And visual studio, 2020 to launch in on the eighth to my gosh. [00:44:10] Frank: I, I love visual studio launches. I hope, I hope there's a good Hanselman. I like a good hour of Hanselman walking me through features, but if there's not, I won't be disappointed. I'm just putting it out there. Scott, I want my one [00:44:22] James: hour, the walkthrough, I believe there might be some Hanselman. I mean, no spoilers or insight information, but I believe there might be some Hanselman involved in things that week. Not me. I'm not gonna, I'm not going to be, I'm not gonna be in Redmond. I'm not going to be around, um, supporting remotely. Let's just say. Working on the keynote for Don at competent. I'm very excited about what is being built, um, and collaborating on and working on stuff. So there's some cool, there's some cool bits and pieces that'll be shown off. Not only how it reload, like we're talking about here, but there's some, uh, I get to, I get to do a little storytelling, so I'm, I'm real excited about that. So anyways, Frank, we did it. We hot reloaded, the reload, and we rebooted the podcast and a hot reload. [00:45:06] Frank: I don't know if it was too hot talking about runtime details and all that kind of stuff. So if you made it this far, congratulations, everyone. But I, it was really fun for me. I don't deep dive. I deep dive into the runtime maybe once or twice a year. And it was just fun for me. And I love how everything has all been sourced now. And I know that's a hot topic. I shouldn't have even said that, but just go home and get hub and go look at all this stuff and go read it and see how it works. And I just really loved deep diving and I appreciate you all coming on this little deep dive. Yes. I [00:45:40] James: appreciate every single one of our listeners. And you can give us more listeners. If you have friends that are like, whoa, they probably are interested in this content because you made it to that in the episode, you probably know people that would also like this content. So good to give them a link to the podcast, merge conflict that IFM thumb to go into their podcast, app merge conflict. What a great name for a podcast and a really help us. Of course, if you're also on a podcast app, leave us a review. I know that. 17 years since this podcast came out, but every review matters and we love every single one of you for being on the journey with us after all these years. And, oh my goodness. Um, it's just been, it had been an adventure, but, uh, I think it's going to do it for this week's podcast. So until next time, I'm James MTSU Magno [00:46:21] Frank: and I'm Frank Krueger. Thanks for listening. Peace.