September 28th, 2020 × #immutability#javascript#records#tuples
Hasty Treat - Records and Tuples in JavaScript
This episode covers immutable records and tuples in JavaScript - new proposed syntax for creating objects and arrays that are deeply immutable and support deep equality checks.
Transcript
Scott Tolinski
Welcome to Syntax.
Scott Tolinski
In this Monday, Sanity trick, we're gonna be talking all about records and tuples in JavaScript and what they are, why you might need to know about them, and what their status is because they're coming. And they're gonna be really, really cool, allow us do some stuff that we've wanted to do in JavaScript for a long time and really will help some of those situations where you want data to be the same thing all the time. So my name is Scott Tolinski. I'm a full stack developer from Denver, Colorado. And with me JS always is Steve West Boss. Hey, everybody. Hey, Wes. And this episode is sponsored by Log Rocket. Node you're gonna wanna check out Log Rocket because it's one of those service this that is just totally cool and is totally different than what you're used to. And you can head over to logrocket.comforward/syntax to check it out. Now what is this? Well, LogRocket is an error exception handling service that allows you to see the errors and bugs happen in real time.
Scott Tolinski
It's so fantastic.
Scott Tolinski
You know what I would love LogRocket for? I would love LogRocket to keep track of the knobs and dials on my audio compressor because my kids always come in here and change it. They always come in here and change it. And what I what would I kill to have a scrubbable replay video to show me exactly what's happening as those kids are turning those knobs? And that's what you get with a LogRocket. It's a video replay of the errors and bugs happening, including the network store, the Redux store that works with all of your stuff you know and love, and it is just one of these fantastic tools that will really eliminate bugs for you. So check it out, logrecord.comforward/syntax.
Scott Tolinski
Oh, right.
Scott Tolinski
Records in tuples or records.
Immutability prevents accidental data changes
Scott Tolinski
Now let's start with the 1st and foremost thing about this topic, which is a big, big thing, which is immutability, which is a big Scott word. Do you wanna talk about immutability?
Wes Bos
Yeah. All of these words are are scary things. Records, tuples. Yeah. These just sound these sound like programming topic. Might as well throw monads in here, Scott. This is a scary end topic.
Wes Bos
It's it's funny. Like, even sometimes I see these, like, tuples. I'm like, oh, what's that? And then I didn't even know what it was when Scott made it, and I just did a quick little reading. I was like, this is awesome. It's just objects ESLint arrays.
Wes Bos
So don't turn us off because it's gonna be good. So Scott said, let's let's start off with immutability. Immutability means when you have some data, whether that's an array or an object or a variable that is a boolean or any of the different types that we have, it means that you cannot change them.
Wes Bos
Meaning that you can if you have an array that is immutable, you can't just add an item to an array. And, generally, the way around that is that you just create a new version of that. So if you ever do need the original piece, you're not accidentally just adding and and removing things, and that can mutability JS of that. The the ability to mutate data can sometimes get you into hot water where you accidentally remove something when you didn't think it was. Like, probably the most popular one is I think it's is it pop? Is pop mutable? Yeah.
Wes Bos
Like, if you pop an item off the end of an array, you're just sometimes people use that because they they just wanna get the last item of the array really quickly. And rather than doing the whole array Scott length minus 1 to reference it, they just pop it. And what you might not have known is that you actually took that out of the original array, and then that can lead to confusion down the road. So that's my short and sweet of what immutability is and why it's important.
Scott Tolinski
It is. People always talk you hear a lot of developers talk about immutability, and you might Node not get it. But once you start having your, like, data assume that it doesn't change JS a new then have to then create something new anytime you're making any modifications for it, That was just a huge breakthrough for me in in code in general. It made me write better JavaScript.
Scott Tolinski
So, I once I embraced immutability, I really, really loved it. Now the bummer about immutability JS we've talked about before or at least in JavaScript currently JS okay. You could define a const string, right, a const string of text, and then you go to change that string.
Scott Tolinski
Doesn't let you do it. Now let's say we have an object and it's a const object and you go to add something to that object and let you do it. It will. Yeah.
Scott Tolinski
And there's like this weird sort of thing where objects are essentially they're tied to their identity of this thing. Right? It's this this object. Right? But not their data. The data inside of an object doesn't necessarily determine whether or not it's the same thing. There's there's some weird stuff around objects there. And so records and tuples are going to help us relieve some of that pain in all sorts of ways. So let's first talk about records and then go into tuples, and then we're gonna talk about all of the things that they do because they're very similar.
Records are immutable objects, tuples are immutable arrays
Scott Tolinski
And the only real difference is that a tuple is an array. So a record is you could think of a record as a immutable object. Right? Hey. We have object. Now we have an immutable well, not yet, but we have we could have an immutable object. And the syntax JS proposed is just a pound and then the normal object syntax. And at that point, the object is a record.
Scott Tolinski
And all of the things you know and love, like object to dot property, whatever you have in your object are going to work the exact same. So by all means, this is extremely similar to just defining an object. You just put a pound sign in front of the brackets.
Scott Tolinski
Now, likewise, tuples are the same thing but for arrays, and a mutable array is going to be a tuple. And the syntax for that is the exact same Wes you just put a pound sign in front of the normal array brackets.
Scott Tolinski
So these things are really simple to get up and running with if you're already using arrays or objects.
Records and tuples are deeply immutable
Scott Tolinski
The only difference is is that they are immutable.
Wes Bos
One question I had immediately when I when you started talking about something, like, how is that different than object dot freeze? Because right now, object dot freeze, if you wrap an object in that, I think it will return a new immutable version of that object, and that's kind of the same idea as this. Right? But the object dot freeze does not go deep. Same with, like, copying an object, it does not do a deep copy. It just does the 1st level. So if you have an object within an object, the nested object will not be copied. It will it will only be a reference to the original Node, same with freezing. It will it will still you'll still be able to modify the nested object, which
Scott Tolinski
kinda defeats the whole purpose of this immutability thing. Right? Yeah. That's all. Looks like this is doing it properly. That's the whole thing with the current JavaScript. That's, like, some people's complaints about the Scott variables, that it's not totally constant. Yeah. Okay. Well, this will help alleviate some of that pain.
Scott Tolinski
Something that you said there was really important. It's not just immutable. It's deeply immutable, and it's deeply in all these things. So, basically, they're calling this a compound primitive, and it can only contain other primitives.
Scott Tolinski
It cannot contain objects. So what are per, other primitives? Well, string number, those types of things. Right? And it can also since a these records and tuples are a compound primitive, it can contain other records and tuples.
Scott Tolinski
So you can have records and tuples nested with inside of each other just by
Wes Bos
specifying that with the the pound sign. Wait. Hold on. Let me look. Can we go through that again? You just said it can't be nested, but it it can be nested. So can you Only primitives
Scott Tolinski
can be nested.
Scott Tolinski
So an object cannot be nested but a tuple or a record because a tuple and a record are a type of thing they're calling a compound primitive, not a object.
Wes Bos
Oh, okay.
Wes Bos
Okay. Makes sense. So are records and tuples going to be a new type, like number, or are they just going to be just something that we have? Because, like, when we got symbol,
Scott Tolinski
that was a new type. But when we got maps and sets, that was not a new type. So they are defining this as a new type. Okay. Here's the thing, values, which will act so I'm reading from the proposal itself. Values which act like other JavaScript primitives but are composed of other constituent values. This document proposes the first 2 compound primitive types, which are record in 2 pull alongside the simple primitive types of string, number, Boolean, undefined, Node symbol, and big hint Node how object is not there. Does that make sense? Yes. Absolutely. This is this is so cool. I'm so excited about this. It's one of those things, like, I feel like I've got a pretty good ear to the ground with what's going on with JavaScript. I had no idea that this was proposed. Yeah. This is my favorite proposal currently because I would love to use some of this stuff. And e okay. If if none of these features so far sound like a killer feature to you or anything like that, you might be thinking, okay. This is fine. Whatever.
Records and tuples support deep equality checks
Scott Tolinski
Let me blow your mind with what could be the killer feature of these things is that they are comparable deeply. They're deeply comparable.
Scott Tolinski
Right now, if you create 2 separate objects, the object just simply has a Node. Name property is equal to Wes. And then the other Node, name property is equal to Wes. Those are the same exact data structures within those objects, and you say, is object a equal to object b? No. They're not. Because in typical objects, what it's doing is it's comparing them by their identity, not by the contents of them.
Scott Tolinski
With records and tuples, you will be able to use the the triple equals to simply compare them deeply. That is if you had a record that was in a record a record that was just 1 property of name, Wes, and then another record that was defined separately with a property of name, Wes, and you compared them, the result would be true. That is so dang cool for people who have been wanting to do this for a long time.
Scott Tolinski
So even the coolest part is it works for the tuples as well. So if you have an array with the exact same contents in it as another array with the exact same constants, if they are both tuples, they will compare to be equal to true.
Scott Tolinski
If they are arrays, they will compare to be equal to false.
Scott Tolinski
So this is so exciting to me. I think this has got killer use cases. This has got, like, the stuff that we would love to do written all over it. I think we had a poll Wes on this where we talked about different solutions for this, and and I think the the solution was to use Lodash and essentially essentially, like, recursively go through the tree to compare the values of everything. I forget what it was because converting it out to a JSON string wouldn't work.
Wes Bos
Yeah. There's not a good solution other than bringing in additional library. And and even then, if it's 40 levels deep of an object, then that gets really expensive to to do that. That's cool that that this is gonna be doable. I was just looking at the GitHub. It looks like they have a little playground where you can actually try some of this code out because there's already a, polyfill? I don't this is a new syntax, so that can't be polyfilled. It's more of a transpile. Right? Like, something like Babel? That's a great question. Yeah. I would imagine you'd have to I would think so. Yeah. You'd have to transpile it. Sets and maps could be polyfilled because it's a a it's not syntax. It's just new, capital s, s e t. But this is literally new syntax where you put a pound in front of your objects and arrays to make them
Scott Tolinski
a record or a tuple. Yeah. And so some other little things here are that they're saying that there's some potential for optimizations in terms of how the browsers do equality checks, manipulating data structures. All these things should be able to be done faster because of how these things are kept track of. Again, these are potential optimizations, not assured optimizations.
Scott Tolinski
Next is it's gonna work really well with TypeScript or any of your type systems.
Scott Tolinski
It also is going to work better than with your debugger than using an external library. So if you're using Vercel library to do this like Immer or something like that, this is going to play much nicer with the debugger.
Scott Tolinski
And lastly, again, as I mentioned, the coolest thing is that they're basically functioning just like objects with slightly different functionality. So that that way, you don't have to learn any more rigid. Yeah. You don't have to learn any weird new techniques or whatever. APIs or anything? You just put a pound in front of it. Yeah. And then you do object dot property, and it works. Yet, it's funny that there is no API because you literally cannot do anything with them. Yeah. You can't add stuff. You can't take stuff out. You just reference
Wes Bos
either the properties, like an object, or you reference the indexes, like, with the square bracket notation.
Wes Bos
The only new API that I did see on this proposal is convert a object or an array to a record or a tuple with the record and tuple Scott from methods. And then there's also a new method on JSON, which will allow you to, parse. So if you've got JSON coming in and you want to parse it into a record or a tuple instead of a an object or an array, there is there's a proposal for JSON. Parsing mutable, which is interesting because maps and sets don't have any support for JSON right now. So but it's interesting that they are going I guess this is much more closer to arrays and objects then.
Scott Tolinski
Yeah.
Records and tuples are new primitive types in JavaScript
Scott Tolinski
So this is at currently in the proposal stage. It is at of the TC 30 9 process. It is currently at stage 2. Now there are 5 stages. Stage 0,
Wes Bos
which is like nothing, really. I don't even know why this thing exists. Have you have you ever even heard of stage 0? I have not. Yes. Stage 0, isn't that just somebody throwing their hat into the ring? We need to do a show on how does stuff get added to JavaScript? Because we did it for CSS, and it was super good. And I don't know very much about it.
Scott Tolinski
So this is in stage 2, which is the draft stage, which is basically where they're going to precisely define the syntax and semantics used for the formal pnpm, saying, like, alright. Let's. Wes got this little strawberry. Now let's do a little chocolate suit on that strawberry. Let's dress it up. Let's make it ready to go to the ball here, getting us ready to go. And, basically, everybody starts weighing in on it where people start developing the actual things that make its way into the standard. And then after that, it will move into a stage 3 as a candidate for implementation and then a finished once it's in the browsers.
Scott Tolinski
So stage 2, it doesn't look like it's going to be in browser browser world super soon. But I like to if something's at stage 3, that means it's, like, really moving along. And at that point, stage 3, I feel comfortable adding it to my programs with a babble plug in or something like that. How do you feel about the different stages and when you can start to use something?
Wes Bos
I'll usually wait for it to be a little further along just because I've been burned in the past. But for something like the nested equality Mhmm. I just like sometimes you just look at a proposal, and then you say, there's no way that's not gonna be added because that is so needed.
Wes Bos
And even though they're all the caveats of this might change, definitely, some of those I'll I'll throw in earlier just to to get them. So I don't Optional chaining. Yeah.
Wes Bos
Yeah.
Wes Bos
Probably wait for it to to gain a little bit more momentum. And, also, like, when these things become more and then they become a lot more like, oh, okay. This is starting to to become that's like, what was it? Backticks. Like, when when backticks first came out, obviously, you can interpolate data, but the tagged template literals, when that first came out, everyone's like, cool, but, like, no one could think of a good idea. I remember, like, going high and low looking for ideas. And now today, there's probably 5 or 6 really good use cases of it. So you gotta wait let people sort of chew on it for a bit. Yeah. Yeah. We all need some time to to masticate here.
Wes Bos
Alright. Anything else to add to this?
Scott Tolinski
No. I don't. I have nothing else. This is very exciting. I'm into it, and I I hope it moves along. Awesome. I'm glad you brought this up. It's funny. Wes
Wes Bos
And And Scott's like, oh, no. This is not what I was thinking of. So we just got this whole entire show out of out of that. So I think next Monday, we'll do another show on what enums are in GraphQL, TypeScript, and maybe JavaScript.
Wes Bos
Yeah.
Wes Bos
Let's do it. Beautiful. Alright. Thanks for tuning in. Catch you on Wednesday.
Wes Bos
Peace.
Wes Bos
Peace.
Scott Tolinski
A review if you like this show.