Jon (00:05.906) Welcome back again to another Gone Mobile. Alan, how's it going? Allan Ritchie (00:10.633) Good, how are you, John? Jon (00:13.407) I think my family is COVID again. So hopefully we get this one finished before I pass out. Allan Ritchie (00:21.333) Well, you look all right today. You don't look sick. You don't look tired, but I assume you're hopped up on your super coffee that you tend to make. So we're gonna be talking about some fun stuff today, but. Jon (00:25.32) No worse than usual. Jon (00:30.615) Yeah. Allan Ritchie (00:37.105) I want to open with, so John is a notorious hard sell for pretty much everything. Everything. I try to get, I pretty much try. Yeah. All the toys, all the, the stuff I'm trying to get you to buy a lightsaber at Disney world. Cause it's, you know, it's too cool. It's just, you have to do it. The other thing I've, yeah, but dude, it's star Wars. It's beyond Epic. You need, you need to do it. Jon (00:43.614) all the things. Jon (00:53.881) They're just so much money Jon (01:02.026) I heard they were hurting now anyway, so maybe they need a little bit of charity, Disney. Yeah. Allan Ritchie (01:07.761) Oh, well. So the other thing that he's notoriously hard to sell on is technologies. John is absolutely insane to sell. But I do have a screenshot, because eventually he did say he had drank the Kool-Aid of DI, or dependency injection. I kept the screenshot, by the way. Kept it. Jon (01:24.95) Well, that one's built in the box now, right? My problem usually is I've found over the years that developing my app, the one app that I make, I've been burned a number of times by taking dependencies on things. And so, you know, usually it goes something like this. It's like, okay, I'll use this thing. And it's like, well, it's not doing that much for me. I could probably write this myself pretty easily. And then, you know, down the rabbit hole you go, or I go. Allan Ritchie (01:27.579) Yeah. Allan Ritchie (01:54.777) Yeah, it's true. But I have the screenshot to prove it. He's in. James Montemagno said the same thing. He was originally against DI. Unfortunately, I didn't get an audio clip of him saying it, but we were having a talk and he's like, you know, I kind of do like DI now because it's in the box. It just has to be in the box. So that's fair. Alright, it's a fair answer. I'll take it. Jon (02:12.918) See, same thing in the box. So what out of box thinking are you doing lately? Allan Ritchie (02:21.433) Oh, this is one I've been waiting for because I've been trying for a couple years and I know the.NET community is not big on it, but they really should be because once you drink this Kool-Aid you're kind of in it for life. And specifically what I'm talking about is Rx or reactive extensions. This has been one I've been trying to pitch John on for years and we're going to see if I can get him into it. Jon (02:47.67) that this has been one that I've specifically avoided and also avoided taking dependencies on things that take dependencies on our X. And I'm curious, you know, that the last time I gave it a hard look was a while ago, I will admit. So maybe things have changed since and some of my concerns are no longer super valid or relevant. So it'll be interesting to see. I mean, you're gonna have to do a pretty good job to get me onto the dark side this episode. Allan Ritchie (03:23.954) I see what you did there. Maybe you need to go buy a red lightsaber at the same time we talk about RX. So I mean really what people want to know first is what's this big deal? And I'm going to say RX because saying reactive extensions every time it's going to, you know, I'm going to run out of saliva. So, right. So Jon (03:27.402) Maybe. Jon (03:38.37) Yeah, we don't need more seconds on the episode of us blabbering. Allan Ritchie (03:45.221) A lot of people want to know what's good about RX. Well, you know, a lot of things hinder on C sharp events. And if you listen to Mads, you know, the C sharp design team and stuff, a lot of them will admit, well, events were a mistake. Um, John, how do you feel about events? Let's start there. Jon (04:04.45) I mean, but yeah, I would tend to side more with that, that school of thought. They're nice in theory, right? But the problem is that of course they're really not super easy to use properly, or at least, even if you do know what you're doing with them, sometimes it's pretty easy to be really lazy about them or. just to have a hard time to properly unsubscribe from things and find the right place to deal with them and stuff like that. And so over time, that has been a bit of a challenge, especially on something like iOS. We actually did a lot of work more recently in iOS, on Maui specifically, to curb our own usage of iOS APIs that have events and not just events, there's other patterns that can weirdly... hold on to circular references because of the whole way that crossing the native interop bridge to iOS and stuff works. So Jonathan Peppers has done a ton of work trying to, first of all, he made an analyzer to help identify some of those situations and then done a bunch of work to clean up our own usages in Maui around them. So clearly, if in Maui itself we're having problems in a lot of cases to try and use events and some of those patterns properly, then yeah, other people are going to. maybe not do the best job of it themselves either. So I'm mixed. I think they can be useful in certain cases, especially in like kind of the multicast case, right? Or like for Android, the pattern has on Android, if you have written against those APIs is very much like listener-based. And you can deal with multicast stuff there too by having a list of listeners that kind of add themselves. But I've always liked the Android pattern of, add listener. Allan Ritchie (05:40.041) Yes. Jon (05:56.33) remove listener and I get to kind of define the interface or not define the interface. I get to implement the interface for that listener and then add myself to it. So what I do a lot in code is like, you know, usage of delegates and stuff instead of events where I'll set like in my own like junk code that isn't public and nobody else is consuming, you know, I'll do like a delegate that I set in a place that gets called so that I'm not actually creating events and stuff. So. Roundabout way, I guess I'm more not Pro events. I'm more pro other things. And so maybe that's a good little foothold for you to have here Allan Ritchie (06:38.069) Oh yes, that's exactly what I was looking for. And if we think about it, right, these events, the event structure, at least the one that C sharp follows, it really doesn't exist in any of the other languages, right? Not Java, not Objective-C, pretty much every other language. We won't even go through them all, right? So they're all based on kind of what you were saying. This delegate, give it like a listener. Objective-C's got their... Jon (06:49.43) Yeah. Jon (07:04.64) Mm-hmm, like callbacks kind of stuff. Allan Ritchie (07:07.069) whose objective see call their stupid things again I'm having a brain fart doesn't matter they have like a messaging kind of thing that goes out but moral of the story is really it's really hard to garbage collect some of those event handlers right and you tend to get the memory leaks be strictly in C sharp because of that it would you would you say it's a fair assumption to say that event handlers are the number one memory leaks Jon (07:09.783) Oh, yeah, me too. Jon (07:22.647) Yeah. Allan Ritchie (07:32.605) that you see with Maui customers and kind of the issues that you guys might fight internally. Jon (07:35.63) Yeah, I think that's I think that's fair to say like I said on iOS There's other patterns that you can encounter that are not super obvious that will also lead to similar leaks but I think if you consider all of the platforms and kind of the typical use case of customers like customers Probably don't as often deal with the iOS API is directly right so they're using like Maui API's and stuff and so Allan Ritchie (08:00.798) Yes. Jon (08:02.942) Yeah, I think that's a fair statement. Allan Ritchie (08:06.505) good. There's my foot holds, my strikes against events. Now, well, it's alright because there is other ways to do it. We get into stuff like actions now. I mean, I find I'm using less and less events anyways where RX isn't available. I'm using more like the function passers, the action passers, etc. And then maybe keeping a list myself, just because. It's a little bit easier. But... Jon (08:10.499) I don't like it, I'm giving you already too much. Jon (08:23.352) Mm-hmm. Jon (08:27.212) Yep. Allan Ritchie (08:34.329) You know, one of the things that I wanted to kind of bring up. So while we've got these footholds is to say like, you know, who invented our X. It was you guys. It was Microsoft. Microsoft invented them. Um, I think it was for the, the Bing, which really nobody uses unless it's forced on you, right? But, um, Bing. Jon (08:42.75) I don't actually. I feel like when you tell me I'll know it. What, who, yeah, okay. Jon (08:57.562) Interesting. I thought you were going to give me a name of somebody. Allan Ritchie (09:01.701) No, no, no. It was Bing that created it. I'm 90% sure on that. It was created for Bing. They used it and then they stopped using it just because they wanted to go to Net8. I don't know. For server side, I find that Rx isn't as big of a deal, to be honest. But when we start talking about Maui, there's some great stuff out there, right? And Rx as a whole pretty much exists everywhere. Like Rx Java is huge. I'm not sure what the JavaScript world thinks of it anymore. They tend to change frameworks every other day, so it's really hard to say for them. Jon (09:36.35) Yeah, I think, well, and we'll get into this a bit too, but like, you know, I maybe need some also help understanding like the difference, but like what does Rx give you on top of some of the, you know, interfaces and patterns that are kind of baked in already? And so like TypeScript has some of that too, right? So like maybe not full Rx, but some of those same interfaces and things. Allan Ritchie (09:51.349) We're getting there, we're getting there. I'm ready. Yeah. Allan Ritchie (10:00.757) So a lot of the stuff is there partially, but some of the stuff that RX does well, and it's RX Swift as well, that was the other one, that's pretty big. But when we talk about events or even callbacks, the problem is they're not really composable, right? It's like, just, I wanna react, let me know when this thing happens, and then you start doing code, right? But what if you wanted to filter that, right? Okay, that sounds pretty easy, you know, I could do, you know, a simple... Jon (10:19.298) Mm-hmm. Jon (10:27.934) And my event handler, I can do some if statements, right? Allan Ritchie (10:31.117) Any new statement? Yeah, you could. What if you want to make it reusable? So that's the first question. If you want to make it... Jon (10:34.146) Pattern matching maybe even. Jon (10:40.849) I can make a method I can pass in as a delegate somewhere. Allan Ritchie (10:44.597) True, true, but you gotta create those things. So that's fair. How about transforms, right? So maybe I wanna get something out of these events, because an event is a stream, right, at the end of the day. So I wanna get that stream, I wanna filter it, so fine, we can filter it relatively easy. We still have to do some boilerplate, but what about transforming it? Kinda same deal, maybe. Jon (10:54.038) Mm-hmm. Jon (11:05.27) Yeah, another method, you know, in and out. Allan Ritchie (11:08.397) Yeah and you have to make it chainable and stuff so well you chaining it is nice. Now what about when we get into stuff like buffering and time windowing and some of the more complicated cases right because a lot of people take that for granted they're like oh I'll just I'll do the calculation right now oh yeah. Jon (11:11.342) Mm-hmm. Maybe. Yeah. Jon (11:18.567) Mmm. Jon (11:27.242) I just throw a timer in. Yeah. Well that, or I'll put some timers in and do some fun things with that. Allan Ritchie (11:34.325) How about sync locking it? Right? What about synchronization? Yeah. You got to do that too. So, so what if I told you some of these things you could do in like one line of code, right in RX. So I could do something like, okay, I want to listen on a, on a sensor change. What? Oh, Jon (11:36.394) Yeah, yeah, sure. Yeah. Jon (11:48.938) Wait, wait, no, wait. How long of one line of code? Because I can make some pretty good one lines of code too that are technically one line. Allan Ritchie (11:59.665) Well, I think one of the things about observables is they're very, uh, composite, right? So I can just keep ticking things on and very easily chain it with out writing a ton of my own code, right? It's, it's very uncommon nowadays to have it go and write something that deals with an observable and then chain onto it. It almost all comes out of the box. So they have stuff like, so I've done a lot of work on like fleet services where you have all these sensors and some of these sensors are just, you know, killing you with info. Jon (12:16.589) Mm-hmm. Allan Ritchie (12:29.009) Right. So you may be only want to take it when you've got, let's say six events, but then I also have to thread lock that because I want six events, but I want data to keep flowing. So when you think about that, okay, it is easy, but you have to think about it and you have to do the work to do the thing. Right. Jon (12:52.834) Right. I might actually write bugs into the code too. Allan Ritchie (12:56.965) right. And the next part of that is like the time windowing, right? So maybe, okay, so I want to get, you know, of those readings, maybe I want to take them averaged so that I can do my, my something like a transform. I want to get the average of those readings, but I want that average to be over 10 seconds, right? So you can do all these composable things where you can say where the Jon (13:10.446) Mm-hmm. Allan Ritchie (13:27.013) transform it after I've buffered an average of 10 seconds, right? And then you get a value. So think about that just in terms of writing that code, right? You have to time stamp everything and say, has it been six seconds? No, or sorry, hasn't been 10 seconds. You have to time stamp everything. Jon (13:41.23) Mm-hmm. Allan Ritchie (13:45.921) and hope that you've kind of done all those calculations properly. Then you have to do the summarization or averaging yourself. You know, I got this many readings, here's the average value, blah blah. Right? This is kind of all stuff that comes out of the box and it's not really easy. Like there's obviously a lot more that RX does. I just like to go into the real big... like these are some key use cases that when you start thinking about it it's hard to do. Jon (13:52.7) Mm-hmm. Jon (14:07.158) Kind of the common examples, right? Yeah. Allan Ritchie (14:12.229) Right. And kind of going back to the events, one of the things that RX does make easy and not that you should do this, but it kind of is something you can get away with is, you know, you create a subscription. So when I subscribe to an observable, I say, I'm interested in knowing about this, but what it does instead of hooking, you know, a hard event. Jon (14:29.357) Mm-hmm. Allan Ritchie (14:34.449) it's giving you like an instance or something that can be garbage collected. Right. There's still ways to pin it. Fine. But for the most part, if you've got that class or you've got that instance, the garbage collector can see it, mark it, kill it. That doesn't mean you do it. You can still be a good citizen and clean these things up and you probably should, but it just kind of helps make things a little bit easier. Right. Jon (14:39.246) Mm-hmm. Allan Ritchie (15:01.801) So far so good. You okay? Jon (15:03.058) Yeah, I think, I think, you know, one of the things to maybe back up a step, because I know I'm still, I won't say I'm confused about it, but it's one of the things that I wasn't immediately, uh, understanding of, which is you've mentioned the word, you know, observable, right? Like what, I know there's some stuff baked into the framework and I think RX builds on top of some of those things. Is that true? Like what can, can you talk a little bit about, you know, what is an observable? Allan Ritchie (15:18.248) Yep. Allan Ritchie (15:29.577) So an observable is actually built into.NET Core. So Iobservable is the interface. It's right in the guts of the runtime or the SDK. I guess the SDK is more appropriate here. Jon (15:38.561) Mm-hmm. Allan Ritchie (15:42.453) as well as eye observer, right? So I'm going, I want an observable, which is how I work with things, and I'm going to observe a thing. So an event, right? An event like a button click, that's a bad example. But I want to watch something and I want to respond to it the same way as an event. And it's just, it's all right there in an easy interface, right? It's like, it's kind of a Jon (16:08.01) What does that interface? Yeah, like maybe we should walk through the interface, right? Because it's not that complex. Allan Ritchie (16:13.801) Well, I think the best thing to do is look at it from the iObserver because that's really the one that says onNext. So here's the next event. I'm going to feed it something. So it has really three methods onNext, onCompleted because observables and events, that's something an event doesn't really have as a completion phase. So maybe you get 10 events and it's done. Jon (16:27.144) Mm-hmm. Allan Ritchie (16:37.246) I mean there's tricks you have to get around there but so it has on completed to say this is the end of the stream and it has an on error right so that's pretty much at the end of the day what an observable does is it emits an observer and you whip things through it on next on here on completed Jon (16:43.918) Mm-hmm. Jon (16:51.362) So is that something that people will often be implementing themselves then? Like what does that look like? Allan Ritchie (16:59.825) You can, you can create it yourself. What reactive extensions does really nice is really build on all these things like the composite methods, right? So the where, the select, the things we're used to from link. It really turns your event stream into link. It's link for an event is the best way of describing it. Jon (17:21.55) So Rx has some implementation that I can say, here is the event and I want you to turn that into an observable or a. Allan Ritchie (17:31.357) Yep, and that's, they've got a call so you can do observable from event. You give it the hook, right? You give it an unhook, right? So it builds that into the box. You can't have a hook without an unhook. Jon (17:38.34) Mm-hmm. Jon (17:44.475) And what does the what's the hook and unhook doing exactly? Allan Ritchie (17:47.805) So it'll be you're doing your plus equals for your event handler, and then your deallocation or minus equals your event handler. So, and that's the other thing that's kind of in the, kind of built out of with reactive extensions is that with everything that you have, we are listening on, there's what you do is you return a method to clean it all up. Jon (17:50.497) Mm-hmm. Allan Ritchie (18:09.821) That's not something you really do in events. You just kind of have to do that thing at some point. But there might be several things. So in an observable, I may listen to maybe multiple events. It's kind of hard to describe here. I'm trying to think of a good scenario, but like a connected and a disconnected. So let's say connectivity. Now I realize you could put a flag out, but maybe they're two separate events. I think in iOS, there might actually be two separate events for that. Jon (18:28.175) Well, you... Okay. Jon (18:34.952) Mm-hmm. Jon (18:38.99) could be. Allan Ritchie (18:40.425) me on that. Don't don't correct me on that. I could be wrong. But you have two events. So I want them to be filtered into one observable, a true or false. So I'm gonna hook both events, but I want my cleanup, which is just basically returning an action. I want my cleanup to deallocate both of those events, right? Because I still have to deal with the memory, but now I don't have to tell the user, yeah you really should clean those things up. Be a good citizen for your app and clean it up. We just do it for you, right? So that's one of the big Jon (18:59.596) Yeah. Jon (19:06.839) Mm-hmm. Allan Ritchie (19:10.555) So I use observables in shiny and the place where they're most valuable is really Bluetooth right because Bluetooth tends to hammer a lot of this stuff like a notification characteristic. So that's when the device is saying, here's my reading, here's my reading, here's my read. It doesn't care. It just keeps feeding you the readings. And then you're going to filter and transform that constantly. I may take a window on it, et cetera. But I'm going to hook several things from the platform to get that one kind of nice juicy observable stream. Jon (19:27.918) Mm-hmm. Jon (19:43.83) one line, yeah, the one stream that's coming back to you. Allan Ritchie (19:48.049) Right, and then because it's again, the native platforms are a little bit weirder, there might be several things I have to unhook, right? So Android, you have to hook to the descriptor, you have to hook to a characteristic, it's just stupid. So users don't necessarily know that. And I don't want to take the time to explain all the intricacies of, of how to clean up an Android because it's hard. So when we talk about cross platform, this is where kind of some of those cool things come in is that I can just kind of do it for you. So you're calling the observable. You say, tell me when my device tells me something, right? And then when I dispose of my description, uh, subscription, just cleaned it up for me, man. I don't care how you do it. I don't care what wild stuff you have to do, which can be quite extreme in some cases. Jon (20:36.886) So is there any like in RX itself, is there anything that's like built in to deal with some platform specific stuff or is that, you know, it's more just the pattern because you're, you know, wiring things up. Allan Ritchie (20:49.565) They did have some wild stuff around threading because they like to manage a lot of the threading under the hood. But that was more UWP Windows phase. And I think that they're slow. I think that they've almost gotten rid of that. It's not really needed with modern.net. But back in that standard days, you know, Windows tends to do some fun things, right? So they had like a special threading model just for Windows. Jon (20:54.098) Okay. Jon (21:09.846) Yeah. Allan Ritchie (21:15.333) If we enter something like reactive UI, so that's a great open source project that's built for Maui, it's built for Blazor. I think they pretty much touch every platform in the.NET ecosystem to be honest. Obviously on each platform, like when we talk about Android and iOS, they have their own thread scheduler, right? So you have to, I don't remember what they both are. Again, this is why I'm cross platform. Once I write it once, I forget the native. So they both have this concept of like a thread scheduler and obviously that's different between iOS and Android, right? So RxUI provides some of these things out of the box. You can also piggyback into Maui's cause Maui has that thread handler, Essentials does, right? So all those great things. Jon (21:48.602) Mm-hmm. Jon (21:58.038) Yep. So do you like, are you using like the, the Rx UI stuff? Is that something you commonly are using in your Maui apps? Like, you know, I think the way that I'm understanding this and please correct me if I'm wrong, is that like Rx at the core is, is really just some nice helper implementations over like the core observable and observer stuff. Is that a fair statement? Okay. Allan Ritchie (22:22.001) Right. Yes, it is. Now it would be the same. You know, I like to describe view models, right? So view model is nothing more than how we describe INPC or I notify property changed, right? Jon (22:34.378) I, yeah, yeah. It's like, I implement that somehow and now I've got a view model. Allan Ritchie (22:38.925) And really it's just the case of saying, here's the magic string property name of what just changed. So I realize a lot of people think that the view models and all the stuff that it does is magic, but it's really not. It just says first name property changed. And then Maui goes, oh, okay, I see your bound here. I'm going to request a read on that property. Right. It does some reflection, but it basically emits it into that value. Jon (23:02.999) Mm-hmm. Allan Ritchie (23:07.313) But we put a lot of magic around this because there's a lot of boilerplate. Maybe we don't want to change. If the first name hasn't changed, maybe I entered Alan twice and we don't need to notify the UI to redraw, right? Then you also have to tell the event to fire. Then you want to say the, you know, if you suffer from long property names and you've got to type all that in, right? So we put a lot of magic. Jon (23:28.982) Yeah. Allan Ritchie (23:30.053) and extensions around view models. So in a lot of cases, RX is just the same. It's putting a lot of magic around two simple interfaces and making it really cool to work with. And I know that it's a tough sell because we're doing a podcast, so I'm not really making John type. but I am going to make him think. So I know he's a bit sick today, but I'm seeing John's face live. So I know he's not that sick that he can't answer some skill testing questions, right? Heh heh. Jon (23:47.448) haha Jon (23:50.669) Yeah. Jon (24:00.747) Well, we'll see, I guess. Allan Ritchie (24:03.521) So what I want to throw out because people just go, Oh, our X is this big, complicated thing. I don't need it. It's too magical. It's hard to understand. And if we talk about the pros and cons, which we will, some of that stuff is true, right? Our X does require a bit of a different thinking, but let's come at this from another angle and say, how would you solve this? If so, you know, John doesn't touch our X, he doesn't care for it, but let me give you some tests, some, some skill testing questions. How would you solve it? Jon (24:18.862) Mm-hmm. Jon (24:30.743) Oh boy. Allan Ritchie (24:33.875) conceptually right and just to get the juices flowing of yeah okay this would kind of suck to make reusable right and I like to not use things like converters and all the XAML stuff like I hate converters if you got converters they're not testable right you have to test them elsewhere so I like stuff to happen in the view right and any of the transformers or what's that other one you guys have extensions right XAML extensions where Jon (24:35.254) Yeah. Jon (24:41.451) Mm-hmm. Jon (24:51.518) Yeah, converters are a sore point. Jon (25:01.314) Mm-hmm. Allan Ritchie (25:03.185) I don't know, localizations are common when I see, I hate it. I don't, my view model is testable. I can get those things to be testable. Converters are baked into the tech. So I have to test them separately. So I like to get this stuff reusable from my view models. So you don't get to use any of your Maui XAML intricacies here. So I'm going to make you, I'm going to take some tools away from you because, because reasons. Jon (25:25.769) Okay. Allan Ritchie (25:28.985) Okay, so let's start nice and easy. Let's start nice and easy. Jon (25:31.654) I like too that we have like a show note page and I would look at it beforehand and I'm like, oh, this is fine. Like you Allen's like, oh, I'm gonna make this, you know I have this idea for the show where I'm gonna, you know Pick your brain on it and convince you and I'm like looking at the you know, the cheat sheet here and it's like Yeah, that's nothing. So you've got a whole other doc somewhere then apparently that yours You've got this and you've been hiding it from me. Oh very sneaky Allan Ritchie (25:54.633) Yes. Yeah, because John gets too prepared for things. He gets prepared for things. And then you're like, okay, well, dudes had time to think of answers. And I was going to hit him live because then this is where, what if I told you I could do X in one line or B in two lines, right? So Jon (26:03.453) Hehehe Allan Ritchie (26:14.421) That's what we're trying to do here. So one of the common ones I love to do in Maui is, and this is right on the reactive UI page, don't search it because I'll hear your keyboard. I'll hear that clickety thing of yours, is something as easy as the user types, right? You may want to do a search. You are looking, I can, yeah, you just, I can see the reflection of your monitor. Jon (26:30.262) I just hit keys. Yeah, I searched for ASDF, and that's not pulling up any answers for me. Allan Ritchie (26:37.453) I could see the reflection of the monitor off your glasses anyway, so I'll be able to tell if you're cheating. Jon (26:40.39) Nice. Sorry, I'm just trying to delay here. Allan Ritchie (26:45.325) Okay, that's fine. So one of the easy ones I like to do is, you know, what people do, like as I'm typing, I want to do a search, right? Let's unpack that right from phase one. You have a view model. So again, you don't, you have an entry, it's bound to a view model, a property that may say search text, for example. from search text in your view model. Again, I've removed Maui. You have no extensions. You have no open source. Let's unpack that. What does that look like to you? What's the first thing you're gonna do? Jon (27:18.894) Well, I've done something like this before, actually. Because you're talking about, I'd start typing, and you don't want to hammer the API, right? Like, is that? OK, OK. Yeah. Allan Ritchie (27:28.597) Okay, Turbo, you're skipping ahead too fast on me here. You're right, you're right. But where are you gonna start, right? Because this is the user thinking, right? Well, I'll just do it as they type. Jon (27:36.102) Right. So you're going to, you're going to start, you know, by getting the text changed or something right of that text box. And you're going to wire that event up and then you're going to start saying, okay, uh, the user is typing. So every time the text changes, I know they've typed something or backspaced something and I potentially want to use that something to go, I don't know, if we're talking like a search API, call that API and pull data back in. Allan Ritchie (28:03.229) Yep, that's it. So you started with an event, okay. And you're right, you skipped ahead on me, of course. That's something you do. I gave you a chance to prepare. I call it breathe. Jon (28:07.063) Yep. Jon (28:13.399) I know this is one of the... I was going to actually ask you earlier. I'm like, is this one of the... what you would call a canonical example of what rx is good at? So maybe I already don't know the answer here. Allan Ritchie (28:26.781) Well, I, but you're prepared for the simple cases. I'm coming up with more, right? I mean, I've got more, don't worry. I'm getting you there. So what I like to say is when the user stops to breathe, right, so you and I can type pretty fast, right? So I'm gonna type a sentence, but let's say I'm searching for a name. A name's a good one because, you know, I might spell your name wrong. I might spell it with an H, right? Jon (28:30.523) Okay, okay. Alright. Jon (28:37.73) Right. Jon (28:48.715) I know where you're going here. I like it. I can't really refute it, but I know where you're going. Allan Ritchie (28:52.333) Okay. So let's say I just spelled J O H of your name. Okay. I typed it really quick. Now I want it to search. I know. No, no, I did that on purpose. I told you, what if I'm gonna have a spelling mistake? I opened with it. I know how to spell your name. Okay. It's a little crappy. That's all right. I'm going to hit you with the breathe. So now I only want you to hit this API when the user stops to breathe. Jon (28:57.93) Right. You'd be spelling it wrong because it's J-O-N, but you know, if it wasn't. Jon (29:09.214) Okay. Well, I'm kind of sick. Remember Jon (29:21.962) Right. So I think in the past I have used a timer and I would start that timer at some point. I forget, I guess when they've started, when it's focused or they've started typing, when the text box isn't empty, right, I would change that timer to say like, okay, I don't know, whatever the value is, maybe it's 500 milliseconds. And every time the text changes, if the timer has not yet elapsed, I would reset the timer. Allan Ritchie (29:23.532) How would you go about doing that? Allan Ritchie (29:28.981) Okay. Jon (29:50.506) so that we continue to wait for that breathing room. And then once they've stopped typing and that time relapses because they've no longer made changes so it doesn't get reset again, I would say, okay, they've paused and now I'm gonna go hit the API and get the results back. Allan Ritchie (30:11.105) Cool. It's a good start. How much code do you think that is? Just to get, just ballpark it. Okay, five or six lines. Now what? Now I took my breath and I start typing again. What's something you might want to happen at that point? Jon (30:14.814) A few lines, five, six lines maybe. Worst case, depends if you're using braces or not. Jon (30:28.286) At that point, well, there could be a couple of things, I guess, if I'm getting really serious about it, if I have a request that's already going out there, maybe I want to cancel it if it hasn't completed because you know, they've already changed what they're typing. So like, is it really in the, you know, is it helpful to return the results back from the previous state still if it's not already back? So I might cancel the exist, the, you know, an existing call that's in process. Uh, and then I would start the timer again, right? Because I know that. Allan Ritchie (30:39.132) Okay. Allan Ritchie (30:52.903) Okay. Jon (30:56.886) Like now they're starting typing again. And I want to, again, catch when they've taken a breath to go query the API. Allan Ritchie (31:03.733) So let's be fair, let's say three lines of more code. So we're up to nine, 10, somewhere in there. Okay. Now, because I spelled your name wrong, see I was leading the witness, I know damn well how to spell your name. Give me a break here. So, I'm gonna go ahead and do this. Jon (31:07.678) Yeah, sure, sure. Yeah, give or take. Jon (31:14.711) Mm-hmm. Jon (31:18.106) I don't know, maybe you didn't read the screen here, I'm not sure. Allan Ritchie (31:23.202) Yeah, so I still have a brain fart and I type the H. So I backspace the H and I type the H again. So the input hasn't really changed based on our last search. Right, so you ran the search twice for the same thing. He canceled it out. Yeah. Jon (31:31.438) No, but I probably got an event for both of those, right? Jon (31:38.258) Maybe. I mean, I, when you hit backspace, I probably started the timer again. And then when you breathe again, the timer will elapse and I would have sent out again. So I guess, I guess if you put it back yet, then I would have done two wrong, you know, two queries for J OH. Okay. Allan Ritchie (31:47.445) great but let's see. Allan Ritchie (31:54.353) Right. So let's unpack that one then because now I've got you in a good spot. Now I got the gun to you. I don't want you to cancel the last one. I want you to keep going because I didn't really change. I'm still searching about your, the misspelling of your name. Right. But so don't cancel that. So what would you do now? I know I'm challenging skill testing question. Jon (32:14.11) Okay. I guess, I guess I would have to keep a cache of like what the last value that I sent to the API was. Right. And then if all these changes happen again, and previously I was going to say, okay, I'll cancel the pending requests because there's something newer. But then I would start to say, well, let's before we cancel it, like let's see if the value that we have now is any different than what we are waiting on the results back for the first request. Right. So I would maybe start to look at that and then obviously keep updating that cache request every time a new one goes out. Like that value. Allan Ritchie (32:48.009) So let's see, how many lines of code do we want to guess at that one? Maybe five-ish? Another three? OK. Three? Jon (32:54.034) Another couple, another three, another three. Yeah, one for the variable and one for like if, you know, if it's the same. Yeah, I guess four, because I have to update the value somewhere. Allan Ritchie (33:03.349) changed and how to cancel for so around 1415 lines okay so we're doing good we're doing good now I also want to validate it so I'm gonna add some filtering it now that to be fair this isn't a lot because it's you know I probably don't want to cancel if it's you know if I don't think you have any numbers in your name thankfully most of us don't I've seen names with Jon (33:10.53) Sure. Jon (33:29.161) I don't think so. Allan Ritchie (33:32.809) You know, we may want to validate stuff and say this is junk input. Who cares? Throw it out. So sure, we could do that in one line of code, but we don't necessarily want to cancel our request either, or do we? I don't know. Right. Jon (33:37.73) Mm-hmm. Jon (33:44.566) Well, you could like use, you know, maybe I would throw a regular expression in there and then I would always filter the value through that so that all of my previous logic is good because it's going to toss out any of the characters I don't care about. Allan Ritchie (33:59.065) Okay so we've got I'd say a relatively good thought oh and there was one other thing I'll put in here but I'm going to let you open reactive UI.com now or sorry.net.net Jon (34:09.498) Hold on. Hold on. Hold on. I was gonna I was expecting that you were also gonna say something about like hey I'm searching for a name and so You know if I if somebody hit like a space Maybe that would clue me in that like they've completed part of the name and I would do a search I'm I swear I'm not I swear I'm not what am I typing in reactive? Allan Ritchie (34:26.025) is already looking at reactive UI because it's exactly okay all right all right all right but reactive UI.net Jon (34:36.824) Alright. Allan Ritchie (34:38.281) These guys are really good because right on their front page, they have a good example. Jon (34:42.482) Or they give you an example. Look at that. Allan Ritchie (34:45.857) So that when any value, when we look at reactive UI is built into your view model. So it's basically looking at that. I notify property changed on property changed event. Okay. So now we know what that does. We're saying, okay, this is the strongly type value, which that's cool. Right. So we don't, we're not going to pass magic strings. So we're saying my search query. I said search text. Yep. So I'm watching that. Jon (34:54.706) Okay. Mm-hmm. Jon (35:05.014) Yep. So that's like the name of basically, right? Jon (35:10.882) Mm-hmm. Allan Ritchie (35:11.065) I'm going to throttle it. So I want to throttle by a certain amount of time. Now we're not going to worry about this task pool scheduler because it can kind of default that stuff, but you said 500 milliseconds, right? So I want, I want to admit this event when they've stopped to breathe for 500 milliseconds. So that's easy for a time span. Jon (35:20.5) Okay. Jon (35:30.198) Mm-hmm. Allan Ritchie (35:34.457) I want to transform it because if I was stupid and I type something and then I backspaced it or it's surprising how many people don't trim strings anymore. Let's be honest. But I want to make sure I'm not searching on empty so I'm going to trim it and what I'm going to say here now. Jon (35:47.853) Yeah. Jon (35:54.734) And that might be where I toss out some like characters I don't care about as well. Allan Ritchie (35:59.929) it potentially, right? So you could say, you know, a replace as an example, if you wanted to. So, but now remember how I said, I only want to admit events where something has changed since the last value. So now as we look at something, and again, we're chaining these methods, we're not writing kind of nested statements or if statements. Yep. Jon (36:04.042) Yeah, if I wanted to, yeah. Jon (36:14.669) Mm-hmm. Jon (36:19.122) Right. So the next thing is after I've throttled, right? So it's, okay. Allan Ritchie (36:25.169) So I stopped to breathe. So I did that J-O-H. I went, Oh, I spelled your name wrong. I backspaced it. I typed H again and it was like, no, you just gave me this one dumbass, right? Back up again. And now I change it to John. I spell your name properly. Now that one's going to come through, right? So the next line, after we've trimmed it, we've done our transform or select Jon (36:34.891) Right. Allan Ritchie (36:46.781) We're saying distinct until changed, right? So what that's doing is saying, don't let anything through unless you're actually giving me a different value since the last time we admitted. So there's some more code savings, right? And again, we're not looking at like this cool kind of chain of ifs, it's all in line, right? So if I don't like the way something's working, I can comment it out, I can reconfigure it, et cetera. It's pretty cool. Jon (36:46.84) Mm-hmm. Jon (37:05.911) Mm-hmm. Allan Ritchie (37:12.433) Now we're going to apply one more condition on it where we say, you know what? I'm not going to search if you just gave me a space or, you know, junk. You haven't given me anything, right? So I'm going to just not do anything. It's my, it's basically my if statement in line. Now these other ones we're not going to worry about either because they're more, you know, get on the main thread, invoke it, I command, right? We don't need to worry about that. The main thing we'd be doing now is probably usually subscribe, right? So we'd be subscribing to an event. and it would give us basically a string because in this case search query is a string. Our transform only trims it, still gives you a string. So it's a string falling all the way through those composite lines to our subscribe. And now from subscribe we can do a lot of cool things. Now we haven't covered the cancel because we get into more complicated things there. But again this is all built into the box. You could be keeping a cancellation token or. Jon (37:53.612) Mm-hmm. Jon (37:57.153) Mm-hmm. Allan Ritchie (38:13.325) an async call that's part of your subscribe and canceling it when it hits because you can say okay well whatever was executing if anything was you know now's the time to stop it and let's start a new one and then when we get that back then we're gonna bind it to a list right so I know it's hard for people to visualize but what I try to do is get like think about the nesting that goes on in your calls right so all those if statements Jon (38:13.537) Right. Allan Ritchie (38:40.561) you know, all of those kinds of properties, cause you're going to keep checking. Like let's say that was called search query text. Like you're going to be typing that a lot, right? You may put an alias on it, whatever, but you don't have to in this chain of events, right? So what RX does is kind of takes all of that nesting and all those lines of code and puts it into one little pretty package. And let's face it, engineers, they like stuff that looks pretty. If it's all in line and it's small like this, you can really kind of digest. Jon (39:08.59) Yeah, no, I mean, it's easy to understand. Like I do like that it is very, you know, that kind of the order is logical, right? Like it's like, okay, I'm doing this, then this, then this, then this, as I chain through it, right? Allan Ritchie (39:22.749) It's clean, right? It's clean. We already said it, it kind of gets away with some of the things that are notoriously hard in kind of the view model, observing all of the things that we have to do. It's all in the box, right? It's like a really cool kind of utility library, but it becomes more because... Jon (39:23.947) Yeah. Jon (39:37.164) Mm-hmm. Allan Ritchie (39:42.109) This is just one simple scenario. I like to get people really going. Now we're not going to for the purpose of this episode. I just like to get people thinking like, just think about that one use case, right? Think about how we buffer something, right? If I wanted to get a lot of events, think of how I want something between a certain time window, which is surprisingly hard, right? So I want an event for an average between now and this, and then I want a new window, right? So I want things bundled. There's so many, it's a lot of complexity that people don't understand. And RX is really good at making that hard stuff easy. Now in that same token, I will say there is a con because we're changing our thinking on this. It can also make some of the easy things hard if you don't think in terms of how RX kind of works, right? It's kind of a paradigm. Jon (40:31.886) Do you have an example that you can think of? Allan Ritchie (40:36.017) we're so used to async and async like when you do an await on an async method, right? It's pretty easy. I, my, I need to not do it in an async void, right? It's going to be an async task. I'm going to await something, right? And that's pretty easy to, to consume because to that it's, it's not really an event. I mean, there is a enumerable async streams or new async enumerables. There's that's what I was looking for. But those are, the syntax kind of makes those nice to work with. Jon (40:41.4) Mm-hmm. Jon (40:59.723) Yeah. Allan Ritchie (41:05.769) but try writing the implementations of them. It's still a bit hard. Jon (41:09.086) Yeah, no, I've actually done that recently. Well, not too recently, not too long ago though. Yeah, they're interesting. They're kind of challenging. Allan Ritchie (41:18.393) Right. So RX has been doing this forever, right? It's good at admitting events and streaming results as opposed to here's your digest it. What it's not good at doing. And this is where I tend to see issues is something like a, like async completes, right? Jon (41:23.743) Mm-hmm. Allan Ritchie (41:34.501) Events don't really complete unless you know they do. Right. So observables don't really solve that. So what I tend to do to see people do is they'll do a two task, which turns it in an observable into an async. But what happens is because that's a stream doesn't complete, right? It just keeps emitting events. So. Jon (41:38.296) Mm-hmm. Jon (41:53.199) Right. Yeah, so it's not what you think it's doing, maybe. Allan Ritchie (41:57.533) But people do this and it never returns and they're like, it's just deadlocked. Well, no, it's never returning. So this is again, where observables, okay, so that's not explicitly understood. It doesn't complete. You have to know that, you have to document it. But one of the things you can do to actually stop that is again, because we're in a link world with these streams is take one. Jon (41:58.956) Yeah. Like, well, no, they never completed. Yeah. Jon (42:11.852) Right. Allan Ritchie (42:21.765) So I can go through all the submit, take one, two task, and it's just like an async, right? Cause I know it's going to complete. Cause the first event that gets admitted in my kind of nice chain of events is what's going to complete the entire call. So that's pretty cool, right? Like, easy. Am I selling you yet or you you're getting ready? Hey. Jon (42:21.919) Okay yeah. Jon (42:36.044) Right. Yeah, yeah. So yeah, you're... Well, I got, I mean, you had your own sheet of questions that you hid from me. I have some as well, surprise. Now the, you know, just kind of quick quiz. How big do you think the assembly size is for system.reactive these days? Allan Ritchie (42:51.429) Alright. H-hit me. Yeah, good. I'm... Oh, I knew you were ready for me. Allan Ritchie (43:10.197) Um, it's up there, but it's shrank quite a bit. Um, I know you, you've got a number, don't you? Do you already have the number in front of it? Yeah. So go, no, I'm not going to guess. Get, let me give you, let me just give me with a number. I won't even bother to guess. Jon (43:16.366) Yeah, I do. Yeah. Yeah, you want to guess? You want to do warm or cold? Jon (43:25.182) No, come on. Okay, do you think it's less than or greater than 5 meg? Allan Ritchie (43:30.133) That's greater than 5 meg. Jon (43:32.463) for system.reactive, just that assembly. Allan Ritchie (43:34.297) Yeah, because that's the whole thing. Yeah. Okay, good. You're looking at NuGet packages, aren't you? Jon (43:38.706) Yeah, I mean, you're going the wrong way. I thought you'd be like, oh, it's like tiny. It's 1.3. It's not too bad. Just for system reactive. Like the NuGet itself is big, but there's a bunch of assemblies in it, right? Like there's, okay, fair. I'm just looking at system.reactive, the package. Now granted, it has dependencies, of course, too. And so like that's what the next question that I was going to arrive at is, you know, with... Allan Ritchie (43:44.243) No, no. Allan Ritchie (43:50.985) Well, there's the link version, right? There's about four assemblies. Jon (44:07.946) with system reactive, like one of the dependencies is syst I've had a lot of problems using that in my apps in the past. And I'm curious, like, you know, in terms of like full AOT release mode, I think even with iOS, did I try? I had problems using another package that happened to use system link expressions pretty heavily. And I eventually went away from it just because I couldn't really get around what I was trying to do without setting that assembly to not AOT and it was an integral part of my app. I didn't I didn't really want to do that. So I'm kind of curious, like, is that something that you've run into using that in your apps? OK. Allan Ritchie (44:51.205) No, and here's the reason why, right? So again, if you do any link in iOS or even any environment where there's gonna be tree shaking going on, right? Those dynamics, like when you get into real dynamic, I guess it would be fair to say that expressions are more reflection-based, right? Truly. Jon (44:57.835) Mm-hmm. Jon (45:10.086) Yes, yes. And I don't think you're always going to hit paths that hit the complicated, you know, for AOT scenarios either, like to be fair. So. Allan Ritchie (45:20.209) Right. So they've got, again, this being reactive extensions at the Ascent of everything that we've talked about is basically a utility library and that I feel like I'm really undercutting what it does Because they're really strong utilities, but that's what they are So you use what utilities you need out of that box, right? So I don't personally find a need to get deep into link expressions, especially where a lot of dynamic craziness can happen And a lot of the wild reflection because if we look at what we're using in reactive UI Just that statement that I've told everybody to kind of look at Jon (45:33.527) Mm-hmm. Jon (45:56.545) Mm-hmm. Allan Ritchie (45:56.849) you're not going to see any expressions like anything dynamic really happening there that requires kind of some runtime interpretation to go on. Right. So it's just not going to hit that. Um, now there's of course ways that you can still hit it. I personally have never run into that. The only apps that I tend to run into expression or reflection based things. I don't know why people are doing this. Maybe this is a bit of a rant, but I tend to still see people trying to use, um, entity framework on, um, on mobile platforms. And I get it. It's a powerful tech. It is. I love entity framework. I don't love entity framework on mobile. It's just, there's not enough power there in my opinion. Jon (46:29.489) Oh, yeah, yeah. Jon (46:39.598) Yeah, it's pretty heavy. I mean, you know, the other thing about that, that I'll take a tangent on quickly is like, if you're using it there, you know, first of all, are you trying to use it to connect to like, you know, a database that's on the network? Cause I don't, um, like I've seen that pattern a lot, right? Where people are like, yeah, I'm trying to connect to like SQL servers. Like, you really shouldn't do that directly from your app. Like I get, maybe there's like enterprise scenarios where you're like, no, it's fine. It's like a, you know, Allan Ritchie (47:02.535) Hehehehe Jon (47:08.886) device on the network that's hardened and we're not concerned about leaking client credentials because it's, you know, a constrained thing. Okay. Yeah. But even that is just like, don't do it. But so for something like SQL light, okay. I get the, it, you know, desire to use it there, but yeah, I think there's still, you know, that's hopefully something that team will keep looking at too is can they make it perform better on mobile, but generally Allan Ritchie (47:15.665) Yeah, they might have a hard cow or something. So everybody's got their own user accounts and permissions, but. Jon (47:38.25) Yeah, I would agree, avoid it. Allan Ritchie (47:40.053) Well, and how well is it going to really work in AOT scenarios, right? Or because they need a lot of deep reflection where expressions are used. Right? So that's what we're talking about is when you get into deep reflection or any type of, well, admit, admit like any reflection emits, obviously they don't work on iOS, so that's the same case with our ex it's got a dependency on it. Yes, it can do some really cool. Jon (47:43.71) Yeah, exactly. Jon (47:49.709) Yeah. Allan Ritchie (48:05.237) kind of reflection and magically pull out some events like it can it can re-hook events for you and deal with all the cleanup but you also don't need to do it you can just bake that in yourself there's a method to say from event you say here's the allocation here's the deallocation go right but you can also just kind of imply it and then it'll go oh there must be an event on this object called this so okay it's nice it saves me a couple lines of code maybe Jon (48:12.406) Mm-hmm. Jon (48:21.984) Right. Allan Ritchie (48:35.465) But do you really need it? I don't know. So to answer your question in a long-winded way as I do, no, I don't hit those issues. Jon (48:43.914) Okay, okay. Um, the other thing that I thought was kind of interesting, just looking at the package and stuff is, you know, they've built it, uh, to target net six, which is fine. Great. You know, that's, that's what they did back in the day. Uh, but since then, there's been a lot of stuff that has come about in the framework for trimming. Right? So like for net eight, there's a whole bunch of new trimming things to kind of think about. Um, so I, you know, I'm would be curious. Like I don't haven't looked at their repository for their issues or anything, but like maybe that's something that's being at least looked at or considered hopefully. Uh, cause that, that can be another thing that impacts your, your linking in a sense of the app, right? Especially on mobile is, is how well some of that works and fine if it's a Meg and it doesn't get linked out, you know, maybe not the end of the world, but hopefully that's something that they're, they're looking at too. Cause that, you know, like historically part of the big turnoff for me for reactive was it used to be heavier, right? Like you kind of said, oh, I think they've trimmed it down a bit. So, you know, to be fair, like one, the size it's at now, probably I wouldn't really think twice too much about, but back in the day that was actually a bigger concern because I feel like it used to be five plus at least just for the core stuff at some point, or like maybe that was the way that it inflated once you fully OTT on iOS or something like that. But it was at the point, you know, where earlier, longer ago, like size mattered more for apps, it doesn't as much now. And it was bigger. So like, it was just kind of one of those like, Oh, do I really want to take the hit? And the other side of that is because like I'll say, and I was actually thinking, you know, we're, we're coming up on kind of end of time for this episode. Maybe we can do a dive in on another, maybe it's another full episode or just kind of a bonus episode. Like how do you start to think about where you can use this in your app? So it makes sense for a lot of the cases that you've, you've suggested and pointed out if you're reading sensor data or stuff that's like coming at you frequently or like the, the text box search example I think is great. Um, but you know, I kind of think through my own app and struggle a little bit to kind of identify where are the places that I would truly benefit from this. Jon (51:08.83) And I don't want to just try and contrive places that could benefit from it. Um, I want to see actual value and that's kind of the, my hesitation over, you know, historically to, to bring this in as like, well, if I'm only using it for just that search box, like, eh, you know, my little janky code is good enough. Right. Um, so I think that's another really interesting part of the conversation is how do you start to kind of look at. Allan Ritchie (51:26.469) Yeah, no, that's fair. Jon (51:34.646) the way your app is built and find more places where this is actually adding a lot of value. Allan Ritchie (51:40.125) I have tons. I started easy though because this is the one that I think ReactiveUI does a good job of selling. There's also great talks if you're looking for kind of a person that really does this good talk. He's the guy I've learned to cheat doing technical talks from. His name is Michael Stonis. He does an excellent talk on Reactive Extensions. He does it all in PowerPoint. He's got the most polished PowerPoint. Jon (51:41.89) Okay, great. Jon (52:04.744) Mm-hmm. Allan Ritchie (52:09.037) He was the guy that's like, dude, why are you doing live tech demos where visual studio could fail? Cause I have bad luck with demoing technology. Um, something always tends to come along and punch me in the face. So he's like, ha ha, you need to learn. Anyhow, he's got a very nice Polish set of samples and a very polished PowerPoint to look at. There is nobody that can sell it better. Um, in my opinion, it's a great talk to listen to you. Jon (52:18.871) Yeah. Jon (52:25.301) Hehehe Jon (52:29.591) Okay. Allan Ritchie (52:38.109) but I would love the chance to continue to upsell you on. I guess it's not upsell right now. It's still a cell. He still has that. He still, he still has that. I don't know, dude. I'm not there yet and that's all right. That's all right. That's all right. Like I said, Jon (52:38.273) Okay, well. Jon (52:45.614) Just sell, flat sell. Jon (52:51.388) I'm still feeling a bit smug about it. Well, here's what we'll do then. Well, let's plan on an episode and maybe we can, I don't know if we wanna do like a, put this more on YouTube or just still try and talk through it, but I'd like to go through my app and kind of figure out, yeah, where are the points that maybe I would actually benefit from more of this? Allan Ritchie (53:15.345) Right. And it's now that the challenge can be sometimes too, is that it's great for UI. Like I said, reactive UI has some really great things that they do. But to me, it's more wide ranging. Like I said, for Bluetooth, it's in my opinion, there is no better tech to do Bluetooth with. It's just there's not. I'd love to be proven wrong. I've tried with some async enumerables. It doesn't go well. So. Jon (53:42.124) Yeah. Allan Ritchie (53:43.91) There may also be other use cases that apply to mobile that are outside of UIs. My long-winded way of saying that. Jon (53:50.206) Yeah, yeah, fair. All right, well, I think this package, plug-in or product of the week is pretty simple again. Yeah, Rx, RxU, reactive UI, I guess we can call the full name here. Does that, I think that's a fair pick, right? Yeah, yeah. Allan Ritchie (54:04.869) Yeah. Yeah, we got two of them this week because they really, if you're doing mobile work, they kind of go. It's it's like peanut butter and toast, man. They just go together. Jon (54:16.766) Well, we can, we can talk more about, you know, reactive UI in that next episode too. Right. I also have my concerns with, with reactive UI too. Allan Ritchie (54:23.167) fair. Allan Ritchie (54:26.549) Oh, no, but you're only worried about the Foddy version that I use, because I use that Foddy thing. I don't really need Foddy to get by with some of the boilerplate. I know what you're focusing on. It is, it's all right. He'll he'll bring it back. That's what it is. Jon (54:30.712) Uhhh... maybe? Jon (54:36.518) Yeah, no, that's not my no, that's not my concern. Well to be continued All right, so that that's our picks of the week Um, I think that does a pretty good intro. I don't know that week. I will declare myself sold, but I will say i'm maybe slightly warming up to the possibility of potentially One day in the far future may be considering the idea of almost putting it in my app. How's that sound? Allan Ritchie (55:14.485) Just to be fair, like I said, I've got a screenshot of him saying he's bought into DI. He did say he would never get a gaming computer, and now he's got the ultimate gaming computer with wood paneling. And he has the ultimate gaming monitor, which he also said he'd never get. So... It's just... Jon (55:25.592) beautiful. Jon (55:31.378) So I gotta take a stand somewhere. This is what you're saying? Okay, yeah, here's where I draw the line. Ha ha. Allan Ritchie (55:33.413) No, you just keep chipping away on him and eventually he'll give in. That's what I'm saying. I'll get you there. Jon (55:39.094) All right. Well, we don't have a winner yet, but I think that does it for this week. Thank you for your best efforts at, you know, trying to move that needle a little bit. And yeah, we'll, to be continued. We'll catch you all next time. Thanks again for listening. Again, you know, if you can give us a like or subscribe, wherever the things are, where you get your podcasts, leave us a review on Apple Podcasts is always super helpful. If you have a show topic or... want to give us some feedback or you want to tell Alan that he's wrong, you can send us an email at show at gonmobile.io or hit our website, you know, drop us a line on one of the social medias, that kind of thing. Thank you all for listening. We'll catch you next time.