mergeconflict351 === [00:00:00] Frank: All [00:00:11] James: right, Frank. I don't get it. I don't get discriminated Unions, type unions understanding F sharp types and why we may bring 'em to see sharp, but. I think we have some of this stuff, but then I don't get this stuff. I just don't understand. But I know they're apparently amazing and everyone loves them. So Frank, I need you to break down what these things are. Cause I remember Miguel Deza telling me the one thing that Afshar or C Sharp could use would be Discriminated unions. And if we had that one feature, we could do anything that, I'm pretty sure that's what he said. quote Miguel. If we quote to quote Miguel Deza, if we had discriminated unions in C Sharp, we could do anything. [00:00:49] Frank: Yeah. Yeah. You can just create a F Sharp project and use 'em from there. They're there. Hi . Oh yeah. Okay. So you actually mentioned two different things. It turns out, so you mentioned Discriminated Unions, which they, oh, they, they've been talking about adding the C Sharp for a little while now, especially ever since they added record. You know, you give a few concessions to the functional programmers and they want everyth. . But then there's also this, um, uh, C sharp, uh, proposal for union types, which is a little bit different actually. Same rough idea, but just different enough to be confusing. So what do you say? We have a very confusing episode about data types, , [00:01:34] James: and they both have unions in the name. So I'm down. [00:01:39] Frank: And they kind of accomplished the same, but in different ways. Okay. Uh, should we do some definitions? Should we try for that? [00:01:46] James: Oh yeah. I'm, I'm down. Let's do it. [00:01:49] Frank: All right. Discriminated Union, it's a data type. It's, uh, you know, just like your structs, like your classes. It's a data type. The thing is, it's a data type with no properties itself, but it can declare little subtypes of itself. So you might have a view data. Discriminated Union. That can be a label or a button or a what, what else is in ui? , you know, UI stuff. image. Uh, yeah, image . Uh, you could think of any other class hierarchy. Um, I think you brought up one earlier. Um, sorry. But when we were talking before the show about. Animal, the classic object oriented programming thing? No, I guess the classic objects oriented is shaped, but animal, you could have a discriminated union of animals, which could be a bird, a dog, a cat, you know, all the animals. So, That's, in a way, that's all they are. Um, and each one of those subtypes, uh, can carry their own data. And so each one specific to that kind of objects needed by that type, but that's roughly all discriminated union is. They get a lot of hype. Um, but I think a lot of the hype comes from, especially from the functional programmers they make writing those class hierarchies, terse. It's really easy to create quick little one level class hierarchies in F sharp and functional languages. And I think that's the feature that we kind of want in C sharp. Uh, cuz yeah. How, how would you do all that stuff in C sharp today? [00:03:30] James: Well, I guess in C Sharp, right? I'm thinking of the animals' class. If, let's say, I. List of animals I would just inherit from animal on those three classes. And then wouldn't those just inherently be animals? [00:03:47] Frank: Yeah. Um, so which animals do you have? [00:03:51] James: I have a cat and a dog. Let's just start with that. We have a cat and a dog. Mm-hmm. . And they both inherit from, Okay. [00:03:58] Frank: And I downloaded your library because I find it very useful, James. Thank you. I love all your libraries. Yeah. Mm-hmm. , and I'm like, Ooh, animal abstract class. I'm gonna add a Frank , the animal called Frank And now all of a sudden, all the, all your code. That deals with animals must now take in these new data types called Franks, even though they're technically obeying the interface. And this is vaguely good object oriented programming. Don't ever write this class hierarchy people. It's bad. Um, It's, it's still a little bit scary from the library author's point of view because people can kind of inject code all over the places, so you can't really make any guarantees about your code anymore. Uh, you wanted this flexible feature of. Inheritance and interfaces and things like that, but you, you kind of , you opened yourself to a million different varieties of, I wanna say a tax, but that's the security person in me. Really. You're just running undefined code. You can't make any guarantees about your code if you have an open class hierarchy. [00:05:09] James: What if I seal that class? Frank [00:05:12] Frank: seal that class up? Yeah. So you'll see this, you see this in, um, big, big libraries out there because people will want to create class hierarchies, but they absolutely do not want users, uh, to extend that class hierarchy. But if you think about it, sealed, not sealed, doesn't do exactly what you want. What I want to say is no one can inherit from this abstract class. Hmm. and Sealed doesn't really do that. Sealed says no one can inherit, uh, from this class. And so then you come up with these awkward things like internally unsealed, externally sealed. I don't, I don't even know you, you have to ask Microsoft experts for how to pull off that, especially special trick. Uh, You know, you just don't have that. Whereas, uh, in a language like Afshar that has discriminated unions, so it's a union because it's a bunch of different kind of objects, it's discriminated because it knows which one of those it is, um, because of the subtype system. And it can only be one of those one at a time. It, it's a close set. You can now make guarantees. You can say, oh, I only handle dogs and cats. I do not handle horses or Franks. [00:06:29] James: Got it. I see what you're saying. So it, I'm defining this type A, A type, right? Like a inter bullying or an animal or something like that. And I'm saying, Hey, listen, this new magical type right now is gonna be limited in. to these specific things. So I could say, um, I don't know, I guess type or something like that or whatever. I'm just looking at the F sharp documentation. FS sharp would be type. Mm-hmm. . I don't know what the C sharp implementation would be. It'd be like type, and it would be, you know, jam James's animals. Right. And then I would say dog and cat and how do I use this thing, I guess is the question. Like, is it, is it basically. Okay. I give this a, a, a new name, so it's kinda like creating a new class, but I'm creating a new type and the type consists only of these two things. And then if I have a method, would I then pass in this new type? [00:07:26] Frank: Yeah, exactly. Huh. Um, so just to make everything super concrete, um, you absolutely are making a new class there, James' Animals would be an abstract class. We're talking about how it gets compiled down to IL here, but I think it's important to know how these things work. Um, then each one of those different ones, dogs and cats, those also become classes. You know, that's how.net works, but they inherit from animals. So it creates your classic polymorphism class hierarchy to do all that stuff. Um, but you have constrained it to just dogs and cats now, anytime you wanna operate on the data . Yeah, [00:08:05] James: that was my next questions, like how do, how do I, how, because, cause I'm thinking, you know, some people are probably thinking immediately, well then I guess what I gotta do is that's kind of as if I'm getting a method, I'm getting an object out of it, and then I. Box it and un then un, you know, unbox it basically. [00:08:21] Frank: Yeah, you kind of do. Um, you might call this, uh, actually C Sharp supports this part, uh, deconstruction, I believe it's called. It's a, yeah, I think so. Uh, it's where you can assign multiple variables from one object. So you'll see this with like point classes that have an X and Y coordinate. You can pull out the. X and y coordinate. You can say Var x, Y equals point, and it will deconstruct the object into its parts. But, uh, that's not quite what we need to do. What we need to do is check the type because. Dogs and cats, those are types of objects. So any function that takes an animal, you don't, you don't write functions that take only dogs. You don't write functions that take only cats. You don't do that. You write functions that take James' Animal. Mm-hmm. . And anytime you wanna inspect those or manipulate 'em or do something, uh, you have to do like a big switch statement. Just like an enum. I, I probably should have said that earlier. Um, in a lot of ways discriminated unions are more like enums than abstract classes, but it's kind of a mixture of the two ideas. So every time you wanna operate on the data, you have to kind of inspect into it with a [00:09:29] James: switch statement. Yeah. I think the problem that I think this solves is also, also is like when I see the pattern matching switch cases, a lot of the examples like take in an object. It's like you can get anything and then it's like, here's this thing I, I mean, obviously you could take in an animal and then you could, you know, decide what animal it is, but then it could be default, could be anything, right? In this case, if it is James', Which is a dog and a cat. Then in that instance, I know that it will only be a dog or a cat. So I could in theory, just pattern match my way out in that with a switch case. Or if a method, for example, only cares about a dog or only a cat, I could say, you know, if you know a is animal, whatever, and you cast it immediately, and then Elif, right? Elsa's gotta be a a dog. So, . [00:10:20] Frank: Yeah, exactly. And um, those kinds of type checks are very fast in.net, so you should feel free to write it that way. It's just when you write it that way, uh, the compiler can't guarantee that you are exhaustively handling every case. Hmm. And it especially, it can do that for enums. If you've ever done a switch over an eNom, I'm sure you've done it a billion times. Yeah. Uh, you'll see the compiler's like, Hey buddy, not handling, uh, this case here. Yeah. You're not handling the color purple or whatever, . And, but it can't do that f for your, um, if BLA is string as if bla is whatever. it can't do that because it could be anything. Um, dot net is rooted in the object, object, . And so you are, you are stuck with that puppy. Everything's an object. The nice thing about, uh, the, the Discriminated Unions is that it can be exhaustive because the set. There's, you tell it which, uh, which types can inherit from it, which ones the interface, however you wanna think about it. it's a type, kind who cares? Um, you tell it that set. Therefore, the compiler knows, therefore, the compiler can yell at you if you don't handle one of those cases. [00:11:41] James: Yeah, that does make quite a bit of sense. Yeah guys, he's, I'm like always looking through a lot of examples too, cuz you know, from how my mind works is like I want to see a use case for it, like inaction. And they have a few in here kind of like you're saying, which is like, they have like type, size, small, medium, large type answer. Yes. No, maybe, and you can kind of like add those on and then say, oh, did you cover every single use case that you have? I'm also thinking about the scenario where, you know, I'm thinking of how I code maybe for, you know, the essentials program or whatever where there's sort of, um, uniquenesses for the platform where you have probably like even some ees, but for example, you might have driving directions and it could be car, you know? Right now it's like I have to create an e I have to create an eNom. This is, yeah, this is what I'm thinking in mind. It's like navigation type. Well, that could be driving. It could. Uh, bicycling. It could be transit, it could be, you know, whatever. But not every operating system has that, so I'm thinking, you know, almost as if there's like type of, you know, navigation on Android and then it's like, oh, here's, here's what you get, right? You get these unions. Or you could, if conditionally compile that basically and narrow that huge set down to something. [00:13:02] Frank: Yeah. And, and let's lean into the EUM analogy because it is good, especially coming from F sharp enums work Great almost all the time when you're trying to discriminate between some data and you're trying to be like, Hey, it's, it's, these parts are common, but there's this one special feature of it. That's what an eum is. Enums are used also as sets for flags, but that's a totally different use for Enums. So it really just kind of comes up like, what if you could have enum. But each eum value could also carry a little piece of data. And now you're like, oh, now enums are way more powerful because now I can have somewhat more generic enums. You know, I don't have to have, uh, perhaps I want to have a drawing program and support backgrounds, and I want to support solid colors and gradients. That's it. That's all I'm ever gonna support. , maybe images in the future. We'll see v3. So I would have an enum that's like, oh, okay, , um, color, red color, green color, blue color, orange. These are all my possible backgrounds. But then I also have to have, um, all the gradients. Oh, it could be, um, gradient from red to blue, red to black. Who cares? All the combinations. They're too hard to write out. as an enum, but you could make that enum a little more generic and say, no, the Enum only has two things. Uh, it's a background, but it can be a solid color, and it takes one bit of data, a color, and then it can also be a gradient. Gradient takes two different things. It takes a stark color and an end color. And so now I have an en. I have that nice clarity of the enum. Here are the two things it can be, but just a little bit of data on the side so that I don't have to have 8 billion enum entries. [00:14:55] James: Yeah, that makes sense. Especially as those things kind of grow, they can kind of get outta control. And I want to define here that when you create this, um, you know, union type. With things in it. You know, when I said dog or cat, those things, dog or cat. It's not, I think, I think this is where my mind is sort of opening up a little bit. Kind of like that extra bit of data you're talking about. Because here's, here's the thing is some people are like, okay, like it could be a dog or a cat. Cuz those are James' animals. Well, yes, but both dog and cat. are type safe inside of this new James' Animals Union type, and they each have their own way of getting to them. So they have like a D dog, C cat, which means inside that type it would be, it could be both, right? [00:15:51] Frank: Either, either. Uh, they're always [00:15:53] James: four. Oh, it's always, or it's not and it's, [00:15:56] Frank: or that's No, no. And is your record type , if you wanna think from a type theory, this is all just set theory. So, uh, a discriminated union type is the, or. With a little bit of extra data to tell you which one of the ORs you're doing and a strt or a class or a record, whatever you wanna call it, that's your, and it's this data and this data and this data. Mm-hmm. , whereas the Discriminated Unions is, it's this data. or this data, or this other data or this other data, uh, you can chain the ORs together. So it's kind of fun type theory in the end usually boils down to just basic set theory, and it's fun to deconstruct your types and think about, uh, which part of set theory you're working in. [00:16:41] James: Got it. So a good example of this would be you create a type, for example, of a switch state and there's two states on and off and you Yeah, in your, you could either be on or off. and it, and instead of having a switch state, which is there both on and off, could do stuff, right? Mm-hmm. , I think it's that. The other part too is if you were just like, oh, I get it. I could have a switch date, and that's just an enum. Well, yeah. Like you're saying, but now, You can actually have like a, a class in it and the, the new type can be on and off, and then you could actually do additional stuff there. So you're saying this new type, which is, you know, Frank's button, it can either be on or off, but then you can decide if it's on or off. And when it's on or off, it can then do stuff. Yeah, [00:17:27] Frank: uh, I, I wanna give a concrete example. I'm, I'm a little afraid it's a bit convoluted, so, yeah. Wish me luck, . Okay, I'm ready. But I do this in my apps all the time. This is honestly my most favorite and biggest use of discriminated unions. You've done this, I'm sure you've done this, um, touch interaction code on mobile devices. Mm-hmm. . So it all starts with, you get a mouse down event or a touchdown. , but you want to track dragging. And then those, those are kind of like mouse move events or touch moved events. And so what happens? You, you create a bull is mouse down, right? . Yep. Yep. And then, uh, when you lift your finger, you set it to false, set it to truth. So we just created a beautiful state variable. Uh, but now you decided, oh, okay. I need to actually track some numbers also. So, uh, when I press the finger down, I'm gonna track the start position. Uh, when they move, I'm gonna track the current position, and then when they lift up, I'm gonna do an operation. So, Ooh, I just added two more state variables. Great fun. and then you're like, oh, hmm, okay. But I also want to handle tapping. So . Now I need another state Variable timing, how long the finger was down and how much it moved. If it didn't move much and it was a short amount of time, oh, it's a tap. It's not actually a drag. Great. What about. Two fingers. I wanna support Zoom also. So, okay, I'm gonna have, I'm gonna have another variable, which is the other finger, and I'm gonna call that alternative and I'm gonna try to track which one is, it gets to be very complicated, very fast. You start creating all these state variables. Some apply to tap, some apply to drag, some apply to pinch. And if you're like me, you name 'em all very poorly. And you always forget which one applies to which and which ones need to be reset. And when. And what you've done, I've done. is create a giant spaghetti mess of state, state variables, and it's really hard to manage. It's hard in my brain to remember which ones to use when. So I use a discriminated union called Touch State. . And for each one of those operations, like one finger down, I track a minimum number of variables. One, one finger down can transition into two finger down if that happens. Or it could transition into one finger moving, which in which case it tracks a different set of variables. It always tracks just the minimum set of variables. It needs to actually do that. It stays in the moving state. Oh, another finger arrived. We're gonna transition into the two finger. Zooming state now, copy over whatever variables you need, create whatever variables you need for the zooming state, but just those variables, you don't have to worry about all the other ones because you're not in that state anymore. The discriminated union values are gonna disappear thanks to the garbage collector, and all of a sudden it just brings organization. Into code. Now I could have had an enum and the Enum would've been saying, um, am I dragging? Am I zooming? Am I doing these other things? But you would still have to remember which of the state variables go with that eum. But with a discriminated union, the variables go with it. The end. That was my example. . [00:20:36] James: No, I think that's a good example. I'm. See it's, uh, I wanna see the code. You know what I mean? I think that's the other thing. I think that it's always fascinating to me cuz it's, there's the, the creation of it. And my, my c sharp brain just has such a hard time wrapping it around the, there's one I'm looking at, which is like, calculate, you know, and it's like, oh, there's, oh yeah, there's, there's like ad subtract, multiply, right? And then it kind of defines, you know, what, what value types they are or whatever and what needs to be passed in. And then, You know, computing that basically and doing other stuff by unwrapping it. So I think that's a fascinating one as well. But I like the idea of like, oh, you're gonna be in a state where there's all these different actions or different things you need to, um, that you need to, um, process keep track of. Yeah. Yeah. And keep track of, but you might not want to, you might not. Support all of them today. You might wanna support a subset, but it also makes it easier to add more into the future cuz you can add them into your discriminated union. [00:21:43] Frank: Uh, yeah, and like I said, I think it just keeps the code clean. It just, you, you have the minimal amount of data for the objects that need it. You're not using, you know, an almost. , big global variables. When you start to create all those state variables inside your class to handle things, um, there are design alternatives for all that too. Have you ever done, um, Link expressions, . Terrible. Yeah. Example. Yeah. Mm-hmm. . So your, your calculate example was making me think of that. That's actually a really classic example of discriminated unions. It's really easy to represent programming languages and computations as a discriminated union. What you say is like, um, , uh uh, you usually have like an expression type and expression could be addition or subtraction. It could be function call, it could be a variable, it could be a number. These are all different kinds of expressions, but we're never gonna allow other kinds of expressions. These are just the kinds of expressions we're gonna allow. Numbers, function calls, whatever, things like that. So it's funny, um, my, uh, continuous, my id, I mean the majority of the code. Discriminated unions. It's, it's just a very nice way to . I mean, once you start to kind of like fall down the path, uh, you know, in object-oriented programming, they do not recommend deep hierarchies. Like if you have to go up 10 levels of base types to figure out what the heck is going on. It's, it's generally not good. It's bad for maintenance. It makes really brittle systems. They generally recommend shallow hi hierarchies and this is the shallowest kind of hierarchy. You can get one level , so it kind of forces you in the same way, like database programming makes you think of like first normal form. Thinking in discriminated unions kind of makes you kind of clean up your app, you know, cuz everything's just one level. [00:23:35] James: Yeah. Think of it as in eye circuit terms a little bit where you have a bunch of widget. But all the, all wi, all widgets can do a base level of things, right, because they all inherit from widget, but then there's a bunch of widgets that only do some things right. And uh, there's other widgets that. Can do those things that those other widgets did, but they also can do other things too. And in my mind then I start to think about, oh well let's just have interfaces for everything. Cuz now widget A can do this thing and widget B can also do that thing and this other thing. And they have like all these interfaces cuz the widgets can do all these things. We're really, I just wanna be able to process those widgets. So I want to create buckets of widgets that I know can do X type of thing, right? These widgets are. Amperages and these widgets, these, these widgets are in two 40 volts while these widgets are in one 20 volts. And am I doing the voltages right? And then these widgets have all the voltages. Does that make sense in some way? Yeah, [00:24:44] Frank: it does. I, I, I, I wanna make the most pedantic correction to what you just said though, so I apologize in advance. Um, you said, so you were doing it all right. Yeah, yeah. These are the widgets that I want to work with. But you said something like funny. , um, uh, I, I can, I can use all these widgets because I know that they can do this thing. You, I you use some kind of language. Yeah. Like that they can do this thing. That's a very object-oriented perspective. Yes. The objects do a thing. Yes. Um, whereas in functional programming, You do things to objects, , and so what, I just want to change your phrasing. What you could have said was, I know how to do things to these objects. Yeah. I don't know how to do things to these, any other kinds of objects, but these objects, I know how to do things to them and. That's kind of the open set versus close set mentality with, with the object oriented approach. You just say like, Hey, if as long as you obey this interface, I'm gonna cross my fingers and just call your code and it's just gonna work. Whereas in the functional world where everyone is a little anal-retentive, , it's more like, no, no. These are the objects I know how to work with and here's how I work. . [00:25:59] James: Yeah. I like that type of thinking of it, which is, I, I look at it, I kind of look at it in a, in a way of like, let's say I'm renting a car. There's a bunch of cars that, that do a bunch of stuff, but there's only a certain amount of cars that I know how to drive. So I create a, a discriminated union of cars, that I can drive, and then I picked the cheapest one. I love [00:26:24] Frank: it. I've never heard that example for it. I've heard a lot of examples. I love it. That one's perfect. You, you took an open set, you made it a closed set. [00:26:33] James: Yeah, exactly. Like when you think about it like this, right, because there are, there's, there's all. There's all these, um, there's all these cars, right? This is a great example cuz there's, there's two, there's two-wheel drive. All-wheel drive, four-wheel drive, right? Uh, stick shift, non-stick shift, right? Automatic. There's all this category. There's open set. And I like this example because, . Um, I, I recently did not do a discriminated union and I accidentally rented a, uh, four-wheel drive, which is not an all-wheel drive. And they are different. Nope, because you have to put the thing into the four-wheel drive instead of the all-wheel drive just doing the thing. So in the, in the types of cars that James would want to rent, cuz that they're the ones that he knows how to drive, that one would be out of the dis the Discriminated Union type. That one doesn't get in there. Uhuh not anymore. I love it. [00:27:26] Frank: What a great analogy. Love it. , uh, they're. Programmatic ones. I, uh, one just occurred to me, um, uh, I'm gonna go from your lovely, lovely analogy, metaphor to, uh, JavaScript. Hi. JavaScript. Have, have you, have you ever used a JavaScript function where they're like, the first argument could be a string, or a list, or a dictionary, you know, well, you know, we'll, we'll handle it. Trust us. Have, have you seen. [00:27:57] James: Yeah, yeah. Yes. [00:27:59] Frank: It's all of JavaScript, what I should say. Um, so those are fun because those are union types. Uh, they say, I can be one of these, or one of these, or one of these, but they're not discriminated union types because you don't tell it which one you're gonna use. Now, JavaScript has reflection, so they usually use reflection. They're like, Hey, are, are you an array? Are you a string? Are you one of those things? But I wanted to use the JavaScript to introduce the concept of just union types where, um, you don't actually. Create maybe even a named type for them, but you just kind of accept mostly for argument passing. You just want to be flexible with your arguments. You're just like, I'll take this or that, or this other thing. I'll figure out a way to deal with them later. Got it. and I bring those up because those have been proposed for C Sharp James. Oh, union types. Number 71 0. You sent me this , you sent me this, uh, this is union types where we got talking about Discriminated union types because there's always talk about those coming to C Sharp, but there has been this proposal for, uh, straight up union types and it looks like. Might be fancy enough to do like the JavaScript tricks where you can have unnamed ones. Mm. Where you can just say dog or cat and not actually, uh, create the umbrella. James', uh, what was it? James' Animals , um, James Animals umbrella. Yeah. Yeah. Um, just, just wanna put it out there that, uh, some crazy things are afoot in the sea Sharp. [00:29:46] James: Yeah, I need to dive through a lot of this. And there was recently a community standup, uh, with I think Matt, uh, war who, Warren, who was the person from the Donnet platform team that has a proposal out there from three weeks ago. So we missed this somehow three weeks ago. And there's a many, many, a thread on, uh, this, uh, lots of input that is for sure. But it's an, it's a nice writeup. It's quite long, but it is different, right? I think it, you know, like you're saying it, it's. As union types, but it's not necessarily, I guess that would lead to discriminated unions. [00:30:20] Frank: Yeah, it's a, it, it's a little tricky because the proposal's a little bit big at the moment. You know, who, who knows which features would actually make it into the language. So it looks like they kind of flip the problem around, usually in a language like, uh, F Sharper Hasco. Any other standard functional languages you would say? Type James' animals equals dog or cat. And in that case you are actually creating three types. You're creating James and Animals the abstract thing, you are creating the dog type class and you're creating the cat class. You're creating all three of those. Uh, the proposal here is a little trickier , whereas you can declare, um, James' animals are dog or. But you have to go declare dog and cat separately. It's not actually defining those in the same place. That said, it looks like they also support defining them in place. So it's quite a huge, um, feature. , it's quite a huge spec is all I'm saying. Uh, they're covering a lot of ground here. Um, Maybe some of it. Maybe all of it. Maybe none of it. Maybe it's maybe one line of it. We'll make it in. Who knows? we'll see. [00:31:38] James: Who knows? Yeah. Yeah, we shall see. Pretty exciting. Yeah. I, I'm interested to see what people think, uh, of this puppy. You know, I'll put a links to the, to the video and also to the, the union types proposal. See what people think of this thing and the language, uh, ideas and. Let me know if you now understand Discriminated Union's author. I, I think I'm getting closer after 30 minutes, but also maybe further away at the same time. So it's a, it's a, it's a battle. So let us know what you think right into the show. Merch Conflict fm, but also if you're, if you want this in C Sharp and why not put it all in there. I [00:32:14] Frank: say, I mean, you, you're never gonna understand them or love them as much as I do until you've used them and actually solve problems with them. And then you're like, oh, these are nice. It's kind of the same thing with the new record types too. Everyone's like, why do we need a record type? It's a shorter way to write the same thing. I'm like, yeah, it's a shorter way to write the same thing. We need those. It's kind of the same thing with discriminated unions. You can of course do all this with polymorphism, but uh, yeah. I do love the shorter way to write. [00:32:42] James: I think especially when, you know, for me, it's like when the tooling helps me and it's like, oh, you could just do this now. Like instead, , you know, good example is it's like, oh, I write this class or whatever, I do this thing. You know, this could just be a record, right? That's what it should do. Yeah. Uh, I think it might, there might be some stuff, but it's like, oh, and here's the thing. It's the same thing. It's like, oh, here's a bunch of stuff. You could do this. I think when I started doing pattern matching more and more, the reason I started to use it more is cuz since it was a feature added, To it later. I intrinsically in my mind, I need to learn a new thing and figure out the use cases. But if the tooling is like, Hey, you know, you can just use this new pattern mat. Oh, that's cool. You know? And now for example, I use the IS pattern matching, you know, stuff all the time. Yeah. like all the time. It's [00:33:25] Frank: great. Yeah, I, I used to joke that all my F sharp code is discriminated unions, and they're called match statements, but they're basically mm-hmm pat the pattern matching statements in F Sharp, that's all my code is. Those and pattern matching functions, . And that's a sign of a good healthy F sharp program. [00:33:44] James: I love it. Love it. All right, well we did it, we did 30 minutes on Discriminated unions. What do you think about that? Frank Little f sharp. We got out of AI and into, into F Sharp. What do. [00:33:54] Frank: I, I, I love it. My, my most favorite subjects, and I feel like if we did go an hour, we would just lose any goodness that we've accomplished so far, because the more you start to talk about these things, the more convoluted the examples become. So hopefully everyone at least got some interest in this and, uh, we'll check it out and think about their own problem. [00:34:16] James: Awesome. Well, thanks everyone for tuning in. I hope that you enjoyed this episode. Let's gonna do it for this week's merge conflict soon. Until next time, I'm James Monte Magno. [00:34:25] Frank: And I'm Frank Krueger. Thanks for listening. Nice.