 So I'm out here trying to get the cats acclimated. Hey, you see this little guy This fat fuck There's like chasing him down, but also keeps laying down He's gonna he's gonna follow him, but then lay down again But you could tell he's not happy even though he's clearly the antagonist. Oh All right, you you really you're gonna go lay down again, aren't you? Yep Cuz he's fucking fat But that little guy Ways eight pounds and this chalk Ways 18 pounds Yeah, you big so Obviously, I want to make sure that He don't do something because he's big enough that he could wreck this little cat But then what do we have this time? Unlike most of the entries in these series this series I do assume that this time around you've actually watched one of the other non-introduction videos And that's the type system comparisons of the type systems If you haven't watched that yet I would recommend that you do I'm gonna have some brief explanations of things to kind of cover it because I know not everybody is going to actually do that Though you should That'll at least have people knowing what the hell I'm actually talking about so the Specific thing that I want to talk about is a race Such a simple type. What is there to really talk about a lot actually types certain types are so Integral to the language how it behaves and what can be done with it What you have to do to get around problems with the arrays that Actually has a really big impact now Many of you know that I am a performance guy so The arrays like they're implemented and say Python Or a fucking joke and I want nothing to do with them, but luckily luckily As far as the performance side of things go I Don't see sure both Implement things well Not a whole lot of complaint. I got to give as far as either of them go So that's pretty awesome where There is stuff to point out that's a Minor minor But the default behavior for passing arrays around in each of these languages is different C-Sharp does them by references a ray itself is a class. So all arrays derived from it Regardless of what the element type is is also a class That's fine. I don't really have a problem with that Certainly is convenient to be able to stack allocate those at times but C-Sharp has ways of doing that in fact you can Define an array, but rather than the new operator use the stack alloc operator and a Pointer or spam Spam is what I would recommend doing nowadays Sometimes they'll just go with a pointer when you get that whole behavior it's still Stack allocated so you I'm not gonna give C-Sharp too much shit. Who are that you? essentially get both Stack allocated in memory like Non-heap allocated memory if you really need that and within the constraints where that type of situation is appropriate Or heap allocated By defaults getting the higher usability that you get out of that a lot of the conveniences that people don't realize Until they have to work without it. It's really handy. So It's simply but Arrays and C-Sharp Typically speaking heap allocated that might not be but overwhelmingly we're going to be talking about this and if that's our heap allocated Okay, I had a Does something very similar to rust the arrays are not heap allocated That being said they don't do what C does an array in C Doesn't have a defined length you Hopefully have set aside enough memory to fit what you intend But you can always go beyond that because what it really looks for for its end is a null terminator Gems a little interesting when you actually have to represent an octet zero zero but I guess just zero octet zero But still you It's no terminate. I done rust and C-Sharp They'll have an actual value that is set aside to indicate the length of the array now it's Allocated if necessary with that specific size. Otherwise it just puts it in there but That's convenient No termination horrible idea One we have to live with at least sometimes so in both at a and rust's case It's not a reference you get the array and for Optimization sake you probably want to pass that around by reference still and I had a Typically will I'm not sure what rusts behavior, but I'm assuming they typically pass that around by reference as well But I'm not super familiar with how rust does things I had a semantics allow a Parameter to be passed by value or by reference in many situations depending on exactly what The rules for it are incredibly complicated. It's nowhere near as straightforward in other languages But they are I think a justifiable complexity, but that's not something I want to get into in this video, but It could be passed around by either depending on things like the size of the array and other factors the Problem you run into with both at and rust is that when you assign a variable that of the type an array and whatever stuff is People coming from other languages, especially languages like C sharp where the array is a reference type expect to be able to assign a new array of a different length to that variable and you can't the Variable that you have is not a reference. It is the specific array So if you've said that's an array of ten elements And it's an array of ten elements exactly if you Do that in C sharp Java Hell Python anything where it's passed around by reference instead If you say you have an array Integer that's ten elements wide Then You can fit Ten elements in that and not have to reuse the reference if the language does Semi-reasonable things and it's probably going to be an immutable array But that's not always the case and sometimes depending on how the language Standard library is set up may be justified and C sharp. I feel like it is but You can also set it a new array of different size The reason that works is because the variable is a reference It was referencing a location in memory where an integer array of ten items long lived but I can now point to a new integer array of 14 items long or four items long or No This is convenient actually Here's it actually an amusing situation where I get to point out something that I had it does that rust doesn't I had it actually gets this right Which is surprising because rust has Years of at his experience to build on Years of taking a look at what I had it does and what it did it do right and copy that and what did it do wrong and Not repeat those mistakes Rust Actually makes this mistake This is where the buy value part about item rusts arrays becomes very important passing an object by value Means that you are passing the entire thing as its data structure is So this means passing the entire array Again, there are Tricks for getting around this you can leave it at the same location in memory You simply create a reference to that but you still need information about that reference It needs to be a so-called fat pointer, which I had access types are But you don't want to use pointers. Ideally, it's understandable you can Return an array created within a function in that a lot of situations where you would want to do that that's hugely useful You can't do that in a rust It's not considered a safe operation. Okay, but is it a dangerous operation and Ida and How does it accomplish this is it simply that it's just too complicated to make it safe or like what's the deal here? Well, it's not considered a safe operation in rust because you wouldn't know the bounds of the array and If you're just pointing to where the array begins, that's definitely true But there are schemes for getting around this Numerous different schemes each with different trade-offs, but what Ida does is there's a second stack that exists within the runtime This is optional if it doesn't exist you get rust like behavior where you can't return an array But if it does exist You can return an array of an unconstrained size from a function When that function returns the secondary stack will hold information about how long that array is and any additional information that the secondary stack needs to hold and Things work as expected So is it dangerous? Not that I found at all not that any experience at a program right now has found Maybe there is something I'm not aware of but I find it much more likely that the rust developers just haven't thought of that solution Now there are other options, of course The fly can flock right off get though There are other options, of course. In fact in the C++ world we can see dozens of these options Or maybe just a dozen but still that's a lot of different implementations for arrays Most of them have to do with strings specifically, but regardless they do apply to any array one such immediately obvious option would be to store the length at the position just before where the array actually begins so the pointer would be to the very beginning of the array and The pointer address minus one would get you the length of the array this works, it's reasonably robust and It's very hackable all you need to do is cast something to a void pointer and Then cast it to an array pointer and you can now access the element just before the element that you were intending to address Because there are functions that'll get you the length of an array by looking at that Which means you have a way to get the integer representation of whatever the data was just before the address That you're supposed to have so that's that's problematic That allows you to in a very minimal way Escape the bounds of where you're actually supposed to be looking into another option It's actually quite brilliant and that I think should be the default way. These are implemented for any language at all especially for strings this is As far as the array implementations goes really more of a string specific thing, but it applies to Arrays in general some of y'all think I like this, but it's no terminated just With some additional things to consider This actually has the very nice implementation detail of it or not implication rather of it being a bounded string by default What I mean by this for the people who are unfamiliar with this part of add-on or unfamiliar with added in general As a bounded string is kind of like a string you see in a database where it has a maximum size But it can easily contain strings that are smaller than it You have to get the length of the actual string out of it, but It'll store anything smaller than it reasonably easily This is how the FB string works if you haven't You're unfamiliar with this Facebook developed it hence FB string it's open source check it out It's fucking awesome. It is one of the most clever designs. I have ever seen for anything in my life It is absolutely brilliant. I love love the design and what it Results in when you allocate an FB string Set aside a chunk of memory The amount of memory stored is put at the very very last address Oh in typical C C plus plus style Allocation for these it allocates one more than what you actually asked for so if you ask for 32 addresses It allocates 33 puts the You know uses the 33rd one as it tended for the null terminator that kind of thing or I think Maybe I'm getting that backwards. Maybe it really gives you 32, but you're only able to use 31 Forget how that works to be perfectly honest. I haven't programmed in C in a very long time either way The last bit bite last bite is reserved And stores The amount of addresses that you can use up Okay, the amount of slots in the array Yeah So why is that special? Why would you put it at the very end? Isn't that a weird spot? What couldn't you override it? It's the amount of Slots you have left to use up. This means that when you got the array originally It's a bunch of zeros Null terminators You add elements to that that counter decrements Eventually you fill the thing and it decrements to zero The null terminator You see how that works now I'm gonna go break up a fight between two of the cats. I'm sure you can guess which ones but So I'd left off about the um the fb string its Remaining count happens to count down to what exists exactly the null terminator anyways Which is very Very clever design That I think It's the ideal implementation for how arrays should exist There isn't really much that does that No standard c++ library Does that although i'm not sure if they could i'm not sure about these c++ standard rules And ador runtime could do that Is it very useful? Actually, yeah when it comes to marshalling between c libraries and as much shits as it gives C It is supposed to default to the normal operating system behavior often c libraries In a huge amount of instances So if your marshalling code doesn't Actually need to change the string at all That's fantastic Would add a be able to do that Nah Not In practice Technically speaking, yes, there's nothing in the arm that is stopping that from happening And I think it should but I can't see any of the add a compiler vendors Actually doing that Notice c sharp or dotnet in general do that No To be perfectly honest with you, I'm not sure exactly where The array length is stored as far as dotnet goes I figure they've probably been smart enough to learn that the um Storing it Just before the actual array exists probably isn't the best option But I'm not sure I haven't looked into the implementation details And who knows maybe parts of the way that the dotnet language works prevents you from being able to abuse that through um Actually, it does So they probably do the simpler thing and put it just before Because that act yeah You can only create pointers to very specific types in in dotnet languages There are incredibly specific rules about what you can create a pointer to Not a reference tons of things can exist as reference type and you can even create references to structs now Then you've got the ref struct is always passed around by reference, but that's something but you can you can create references to value types I'm talking pointers Done simple pointers It's got very strict rules on what you could do with them and while you could cast it to avoid pointer you could not then cast it to a integer array or any other type of array and get the index minus one to escape it Even if you were a try You're going to get an exception because it's still managed pointers There's still tons of checking to make sure stuff's done safely reasonably safely It's still unsafe code, but it's you know reasonably safely but You wouldn't even be able to cast it to the array type in the first place because that's not an allowable type as a pointer You can use pointers like arrays in an unsafe context when you have a pointer type the array indexer is actually a pointer offset but again There is enough checking even though it's unsafe code to make sure that you don't index outside of where You reasonably should So no special pointer trickery. So yeah, they probably do just store it right before the array itself Not a bad idea You know, you have that checking, you know, you have that safety That's probably what they do, but this isn't only about how arrays are implemented There's another factor that I think is something that I did us horribly horribly wrong the whole reason why should have watched the previous video on the type systems in general is that Ida does nominative typing whereas dot net doesn't dot net is much more of a Structural class wide kind of thing going on You can kind of view it as in dot net the arrays are anonymous and If Ida had a syntax for an anonymous array much like they do have for anonymous access types you'd be able to get around this Well, they add such a thing I doubt it. I strongly think they should Especially considering Ida has the potential to be a major player as far as numerical computing languages goes has the potential to take over for train, but Well, they make the right decisions to accomplish that No, I don't think so Anonymous arrays would be one of the required things as far as that goes The reason for it Well, when you define new functions, they have to take a type You can't do an anonymous array type So what you have to do is define a new array of the numeric elements that is unbounded Unconstrained rather not unbounded unconstrained It'll have its bounds at the creation site, but Those bounds can vary So that's unconstrained So It's fine and dandy and all but it does mean you Now have to write those functions to those specific names Somebody else comes along writes another complimentary mathematics package You Don't implement each other's stuff It has its own Name for an integer array Still of the same exact element Still unconstrained But has a different name Even if the immediate name is the same the full fully qualified names are different And that means they are still incompatible in a nominative system functions written For one of these names are incompatible with functions written for the other name You have to cast The arrays between the two names Seriously No actual conversion happens. There's no performance overhead for this Assuming the compiler is smart enough to realize that they are structurally identical If the compiler is not smart enough for that, well You're gonna have checks that literally don't need to be done So that's fun, but Even even if it's smart enough to recognize that those checks don't need to be there and can be completely removed That still litters your code You've got Tunk conversions all over the place that do not need to be there Because they are the same And if you had an anonymous type it could work for any Array of integer any array of float any array of Decimal sure can do that in not net Sure can do that in well the majority of languages nominative has uses nominative typing has its uses I'd mentioned that in the type systems video There are situations where you want very particular semantics and having a name behind it to enforce that is useful But that should be in addition to the language at a later point Anonymous arrays should be there from the very beginning With named arrays being added in later Not the other way around This makes it very very difficult to develop Very tedious rather. It's not difficult. It's not like it's hard to do this, but it's incredibly tedious to do this in Ida To have to create a type and use that type name throughout everything and Even if you're the consumer of it to to regularly cast between two different things because the library One of the libraries that you're doing doesn't have stuff that the other one does and you need stuff from both of them It's just a pain in the ass Whereas in the dot net world each of them can just write their functions for arrays of The different numeric types That's ridiculous arrays in Many languages could use a lot. It's a bit of work, but They could use a lot of work in Ida Ida loses big time on this one This isn't even a situation where I can argue that it is justifiable in a specific niche and that that niche happens to Fit exactly what the language niches anyways This is literally just Ida fucked up until the next video Have a good one guys