 Continuing on with the different parts of Aida's type system, this time around I'd like to talk about records. They're also kind of known as structs or structures in many other common languages, but it's a way of grouping different values into what would conceptually be one value. Records, a little tricky, just given that they are the basis for a lot of different things, so for this video it's just going to be the simplest forms of records, largely analogous to the struct or structure that you see in other languages. So it's not going to be involving discriminants or variant records, there's not going to be any use of tagged records or extensions of them, it's just going to be the most basic struct. So let's begin with the actual declaration of it. This is done rather simply by just type and then the name, similar to, I don't want to say every, but definitely most type declarations go this way. And then just the record clause, which is going to complain about a little bit, just because the auto-complete isn't super happy with it. But a empty record, we'll start from there, I typically build up a little bit, but an empty record just sort of looks like this, that's oddly slow for one thing. I think some background processes might be going on with my computer, so if the build seemed a little slow, sorry about that, it's definitely seeming slow to me. Now, I'll show this again in a later video where it's a bit more relevant, but there is some shorthand for empty records, I'd like to just get out of the way. And that's just this, see it builds just the same. This is really something that exists more for record extensions, if you happen to have some abstract record that other things are going to inherit from, that may be empty, but then the other, the children that inherit from it may add new values or the other way around, you may inherit from something that you don't need to add any values to but are adding new functions and procedures that are associated with it. That, this is really where that shines. As far as basic records go, I've never seen a need for declaring an empty record under any conditions. Maybe there is one, just because I haven't seen it doesn't mean that it doesn't exist. But I'm showing it nonetheless, just because this is something that you can do, there's got to be some use for it even in non-tagged, non-extending environments. As for a more useful one, and let's do that still. Let's just continue with my very literal first value. Just do an integer and second value. We'll make this one a character. Just so that we have some variety, how you can see that this isn't quite like an array, but that rather we're doing different data types that are grouped together. Now, we will need to actually assign this to a value, because currently we just have the type described. And we'll just do x of example. Now as for assigning, I'll give a little bit of a crash course here. I'll have another video where I go into more depth in this, because this is actually a rather important thing that Aida does that's quite different from a lot of other common languages. In this instance, the example value is actually sort of assigned already. There is an x that we can use, and I can show that off if we, mixing up my languages, if we do this. You see that it does catch that this seems to be a little bit of an unusual condition. It's not an error, because it will have defaults as you're about to see, but it's generally expected that you are going to assign something. So the fact that it's not means this is probably some error condition. And right, because the program is definitely not called x, it's called records. That was dumb of me. Now these should largely seem nonsensical, and that's just because they happen to be the default values that were pulled out of somewhere. That's a complicated thing having to do with the reference manual, and just ignore it largely. If you're seeing just very odd values like this, chances are you would have been a null dereference exception in other languages. Just Aida uses defaults of some sort. But back to where we were getting to, to actually assign values to this, there's two different approaches that you can take. One that should be very familiar with coming from other languages, is to just do a positional assignment in what Aida calls an aggregate, and that's what these parentheses are for. So we'll do, I don't know, 12 and B. Oh, I did that again. So we build this, and run this, and you can see that they're actually 12B now. Now at least in this instance, the aggregate is pretty obvious. Sometimes we need to be clear about this, and that's actually done by just putting the type name. So in this case, example, along with an apostrophe right before the aggregate. So this just makes it clear that what we're defining is of the type example. But considering it could figure that out on its own, this will not actually change anything about the code. We run this, we get the same results. And the other approach that we can take for this, and I'm going to rearrange these, is through the names of the fields that we're actually assigning. So we can do second value, just put it out of order to make it clear that this works. And we'll do G, I guess, and then first value. That's clearly a little bug in the syntax highlighter. And we get 7 and G, like we should, we said first value was 7, we said the second value was G. I'm not sure actually if these can be mixed, I would assume don't... Oh no no no, yes they can be mixed, I've done that a lot when writing out the testing frame, stuff for unit tests. These can be mixed, I generally recommend again stitch if you're at the point where you need to use named values or named fields for whatever reason, you probably just want to stick with that. Even more so just from my experiences with actually maintaining software that's been developed, not just writing it in the first place. Given that your record layouts can change or that different things in the record can be added or even removed, you probably want to stick with the names any ways, like just treat that as your default approach, unless for some reason you're very certain that it's never going to change. Yes it's a little bit more typing but it helps with bugs later down the road. So the great example I can give of that is if for some reason, maybe having to do with how the record just needs to be laid out for performance reasons, we have the third value in between the first and the second value. In this instance, it's not going to care but if we were instead, well I can also do this just to show what happens exactly when we haven't added it yet. You see that it says specifically that there's no value supplied for the field with the component third value. If we were instead using positional stuff, so that was seven, and then she, I think a few of you probably expected this. It thinks there was no value supplied for the second value, and clearly there was meant to be but because the layout, the actual order of the components in the record has changed. It's confused about this, it thinks that this is actually supposed to be the third value now when we clearly intended it for it to be the second value. Well not clearly, you use the name so that you can be clear that it's the second value. So it just helps a little bit with the maintenance in the long run. And of course we can fix this with just a little bit of that. Like I said, generally better if you stick with using the names. Another thing, typically with modern languages you see this regularly in some way or another. Not so much when NIDA was in its infancy is that you can actually assign defaults. Let's do it to the third one. But you can assign defaults to these numbers. So let's default third value to 100, and because we're assigning all of them here, you won't actually see a change. However, let's mix the positional and name stuff a bit. Let's do... And then third value. Let's just say that we don't really care what this is, just use whatever the default is. Well that's done by this little box. So I gotta fix that stuff, but that's for something else. So now in this instance, because we're telling it to use the default for the third value and we have a clearly defined default there, it'll use 100. As for if no default is defined, I believe that's treated just like if you had never assigned it in the first place. Although I don't recall. Okay, so it did use a default, for some reason that default is different. Maybe it has to do with how the layout has changed. That is a whole complicated thing, but you can tell it to use a default if there's no default actually defined for this. And what it will do instead is use the default for whatever the type itself is. Those are going to be wildly unexpected. I've seen them very even from just different computers. So typically speaking, you don't want to do that. Another thing that we can do... And this may be useful if you plan on things being extended later, but don't necessarily need to be explicit about what the new things need to be. That's sort of a catch-all for the other values. And it's quite literally with the keyword others. And you can use default just the same. You see, you caught that both. One thing you do want to be a little bit careful of when using these, of course, is that because the others can be of different types, if you happen to do something like R this time, this will fail. Because while it can use the R default for the... Oh, excuse me. For the second value. R is not a valid value for the third value, who expects the type to be of an integer. We can reverse this by giving it an integer instead, and then it complains the exact other way around. While 54 is totally fine value for the third value, it's not of the type character, so it collides with the second value when we get that error. Let's go back to using the default for that. Now we're going to get into a little bit more of an advanced topic as far as records go, and that's for being a bit more clear about exactly how the layout is. And we're sort of hoping that I can remember how this works. It's been a while. I might need to look this up. So we'll see. You know what? Yeah, I am going to look this up just so I'm not trying random stuff. Okay, so minor thing I was forgetting. This still has the record arch. And I believe this is just like first value, 0, range, and this should be, well, to be a 32-bit integer, but let's say, yeah, this one can be fine. We'll just go 0 to 32, and then we'll do second value at, I have to do this one, 33 through... No, no, no, no. This would be 231, and then this would be 32 through. So if we did 32, it would be up to 60, well, 63. But let's give this one an excess. The next one would be 96. We got 94, 95, and then third value at 6 through 27. Hopefully I did that right. And it looks like it did. It looks like everything can fit really quick. I'm going to show you what happens if something does not fit. So there's no way for a 32-bit integer to fit into a 16-bit space. And you see that it's complaining about it being too small now. Very unexpected. But there's nothing stopping it from fitting in way too large of a space. So a 32-bit integer will obviously fit in a 64-bit space. This really creates an unnecessary amount of padding. But it's that padding that makes this very useful. I've never used these record representation clauses for anything other than protocols. Sending chunks of data from one machine to another, the record clauses allow the padding that's put in a lot of these protocols to be written very easily. But I never personally use these for anything other than that. I'm sure they're useful for things. That's just the only thing I've ever actually seen it for. So we can go ahead and remove this. It's nothing we really need to see now. Limited. That would be the last part. So one last quick little part. We have this defined here. But one thing that's true with a lot of values in Ida is that they are mutable or able to be changed. This isn't always a good thing because we can do things like this. Let's give it a first value of one, a second value of a fan, a third value of... It'll be 100 now. Let's give it 500. All right. So we just got to move that around. That's my bad. Clearly taken from the original definition but the third value is taken from the re-signed one. This may be something that you want. This may be a acceptable behavior but for a lot of situations it's actually not behavior you want. And there is a way of restricting this. If we go in and make this instead a limited assignment is not valid. Is not something that you can do because this is a limited type. Because this initial assignment is acceptable. It just prevents any assignment after the actual code starts. So essentially you can only declare it once when the variable is defined after that point any attempts to... This does not strictly stop mutation because if we go with this approach instead you can see that we still changed it but we changed this one's third value to 500 rather than assigning X to another example type. This can further be restricted by actually moving this to the private part so that none of these are... are readable. At least publicly. That starts to get into a little bit of a... really more of like visibility and scope than anything having to do with records because that doesn't change how the record works or how it's laid out or anything. That's more of a visibility thing and so that's something I'll cover in another video. But at this point you should be fully equipped to handle everything involving basic records as they are analogous structures or structures. Like I mentioned there's a few other things that need to be covered because they expand upon these and that's things like discriminants and variant records as well as tagging which is used for record extension which then is used for implementing object-oriented facilities. Probably going to get to the discriminated variant records before the tag records even though the tag records are more relevant to most people. I'm not... I'm not certain on which I want to do yet though. So yeah, if you found this video helpful please consider giving a thumbs up and also consider subscribing and the little frickin' notification bell if YouTube's weird. Yeah. So until then... until the next video that is... Bye for now.