 So, today we're going to discuss objects. What is an object? What is object-oriented programming? What makes a language object-oriented? Things like that. So first, the different practices involved. As for full object orientation, the people who are fond of object-oriented programming find that they generally perceive objects as good, as this very beneficial thing to use. It may claims that it requires less code than... This is usually said in comparison to structured procedural or imperative programming. This isn't necessarily said in comparison to something like functional programming. Just know that in practice you see a huge amount of interleaving in different paradigms, so it's not like you'll often see just an object-oriented language. They also claim that it makes a code more structured. Now there are tons of different structuring approaches. I usually see this as a comparison to the completely unstructured procedural style code. We're talking way back before namespaces or modules or anything like that. Nowadays, even a strictly procedural language or a multi-paradigm language that you're just not using objects can still be highly structured just because of other approaches to tackling structuring the code. Get into that and get into code structuring in another presentation. I also claim that it makes it easier to test. This has to do with the objects being a bit of a black box. We'll get into what that means later on in this. And also that the inheritance and stuff helps enforce similar behavior throughout the descendants that, when it's already verified in one, should work properly in all of the descendants. I don't really have anything else to say about that there. But there are a lot of other claims. You're probably seeing this on YouTube, so if you go through, go on to the YouTube search and what is object-oriented programming, you'll find tons of videos that detail tons of other claims about what object-oriented programming is. I don't want to discuss everything because I'm trying to make this more of a crash course. And generally, the people who are fond of object-oriented programming want to use them not quite everywhere for anything, being a little bit hyperbolic here. But there are languages, like C-sharp, that pretty much do use objects for everything imaginable. But then there are others that are generally regarded as object-oriented, like Java, where there are some base types that are not objects. But then there's this huge object tree along with it. But generally speaking, somebody in favor of object-oriented programming wants to use them as much as possible. So then what makes a language object-oriented? Because we've got to cover this. One common thing I see asked tons of different places is, is this language object-oriented or claims about this language is not really object-oriented or is, despite criticisms, so what actually makes a language object-oriented? And it depends on who you ask. Alan Kaye, one of the most important people in defining what object-oriented programming is. One of the pioneers in object-oriented programming. I won a Turing Award in 2003 if my memory serves me right, specifically for his work on object-oriented programming. Says that really the focus is on message passing over calling, and that's a little bit of a technical detail that we're not going to get into for this. I got a presentation on sub-routines that'll have that in there. But the common definition doesn't quite line up with what Alan Kaye originally proposed. The common definition is that an object-oriented language should support things like inheritance, whereby one object inherits the values and properties and methods of another object. Polymorphism, whereby one object can represent itself as another within the branch in the object hierarchy. Get into that and get into the specifics on these in a little bit. As well as others like late-binding and other stuff, they get into a little bit more of these in a bit. But it's... This is really something where object-oriented means different things depending on who you ask. I have a quote here from Alan Kaye. I'm sorry that I long ago coined the term objects for this topic, because it gets many people to focus on the lesser idea. The big idea is messaging. So then object-oriented or object-based. And unfortunately, the use of these terms is the no-true Scotsman fallacy. What you can see over and over again is people look at, however, their language of preference implements object-orientation and say that is the one true object-oriented language approach. Everything else is object-based. So it's unfortunate. But just be aware that since this is such a remarkably popular paradigm, you wind up with, like everything else, tons of different definitions for what should sort of be the exact same thing. But I'm not going to give my opinion on what makes something specifically object-oriented or object-based. I personally go with Kaye's definition. But often when I speak about it, I'll use the common definition just because I'm trying to speak to the general audience here, not to Alan Kaye and his contemporaries. But I also want to touch sort of on prototyping, just that it's another approach to object-orientation that will usually get you yelled at if you ever call it object-orientation. It sort of implements a lot of the common definition parts of objects. But overwhelmingly, it will get called object-based. I think that usually has to do a lot, at least the biggest, the most common criticism I see, is that, oh, well, it doesn't follow a class hierarchy. But there are other ways, beyond prototyping, to meet all of their other parts of the definition without actually having the class. ADA is like this, where it implements, inherits some polymorphism and late binding and tons of other things, dynamic dispatching and just nearly everything that people would describe as something an object-oriented language should have, but lacks the actual class. It has a different approach to structuring that. And so, as for prototyping, I don't really want to say a whole lot here, just because I don't... I haven't worked with prototyping languages often enough to feel comfortable really giving an authoritative description of what prototyping is. I've done some work in JavaScript enough to write something for a client, but I didn't really make much use of prototyping in that. Maybe it would have benefited me highly if I had used it more. I just didn't. You can find people easily who know prototyping considerably better than I do. If you want to get anything on prototyping, I would highly suggest you go with them. I'll try and get a link from somebody. I've seen a few videos on this before, just guy doing amazing things with JavaScript specifically, using prototyping. I'll see if I can dig his stuff up and have a link for it down in the video description, just to help get you started on prototyping. So then, my practice is specifically, because I'm not going to pretend that I'm unbiased here, I probably tell a little bit of the undertones in that I'm not super keen on object-oriented programming. They are sometimes useful. If you delve into my containers library, especially, you can see that almost the entire thing, container-wise, is an object hierarchy. There's the base container, the different types of lists, all inherit from a list container, which inherits from the base container. It's just a huge branching tree. But there's plenty of cases where something being an object is not actually beneficial, or in some cases can actually be detrimental. And that's why, again, if you go into the containers library, you can notice that the nodes that make up the containers are not objects. There are base records that don't inherit from anything. This decision, at least in that specific case, has to do with memory overted of the record tag, as Ada calls it, or the vtable, as C++ calls it. I'm sure there's other names, depending on the language, but there's overhead for that that not all programmers are going to be aware of. And in some cases, that can be a rather significant amount of memory use that's added for each node. So for something like that, I find it best to avoid it. Similarly, I'm very glad that in an Ada, all the numerics types are not objects. For, again, the same reason the additional memory overhead of all the numbers would be absolutely ridiculous. At least on the processor I have, a 64-bit integer as an object would take up 128 bits. You do a lot of numbers in memory. That extra amount from the tag really adds up. But also, if you're using an object or intended language that follows K's definition and actually uses message passing over subroutine calling, the way message passing is implemented, even though it has certain benefits, does result in copies in memory. Which, if you haven't seen the video where I discuss memory performance, there's a few of them actually, accessing anything in memory, copying anything in memory. We're at a point where it's taking several hundred CPU cycles for any single memory operation, and it's causing quite a bit of performance degradation. So I find it best to avoid that with certain things. Essentially, I view it as a trade-off. Understand where it's good, understand where it's bad, and weigh those with any design. And pick the one that's most appropriate for the goals you're trying to accomplish. I don't think there is any universal approach to things. So as for objects themselves, an object groups data together. This is very similar to a record. The major difference is that an object also groups functions along with it, as long as those functions are dispatching. That is a topic for another time, but at least with class-based object-oriented languages, whether or not a function meets the appropriate definition of a method is very easy to determine. If it's inside the class, it's dispatching. It will be a method. If it's outside of the class, it's just an ordinary function. OK, I already covered that. Primitive functions dispatch. Don't worry about the name definition, it's not very important. But primitive functions are dispatching. So objects are a way of providing encapsulation. And you may have heard this term used to describe other things like namespaces and packages. It's a container, not in the sense of the containers or abstract data type library, but a container in just the general worldly sense, like a bucket is a container. It holds a bunch of things. In the case of an object, it holds values and dispatching methods. So where a class varies from a namespace, namespaces can hold other namespaces. Namespaces can hold classes. A class can, in some languages, hold other classes. But a class cannot hold a namespace. Classes are just definitions and need to be instantiated as you would instantiate a normal value, like an integer. You give it a name and then give it its initial value. Namespaces just exist from the get go. Once that code is loaded, it's just there. It doesn't need to be instantiated. This also means that only one instance of a namespace can ever exist. Classes, unless they use a singleton pattern, can exist as many times as you have memory to fit the instances. So our class differs from a package. Many of the same things for a namespace also apply here. But note that if you have classes and packages available, it's generally better to implement singletons using the package itself and not through a singleton pattern with a class. So for inheritance, let's say you have a class just called A and then it moves. You have a class B that talks. And it inherits from A, so it also moves. That's how inheritance works. Just by virtue of inheritance, the moves method or however it's moving is also provided to class B. That's why it helps cut back on code and the amount of code you write. So as for polymorphism, say you have a class A and you have a class B. B inherits from A. You have a class C. C does not inherit from A or B, but it has a method or collection of methods that act upon As. And so because B inherits from A, you can pass anything of the type class B to the method from C and it will work because it reduces the view down of B to anything A has but not anything that B adds on to A and then operates on the limited view of B, as if it were A. So as for generics with object-oriented programming, it largely works the same way as you would expect. If we have method A from a class that acts upon a generic type then you have it should be written slightly differently. If you have a class that inherits from the same class that method A was in, let's call that class B. And the class is specified to work on integers. Method A will also work on integers. Then you have a class C, which would be inherited through a float. The method A would work similarly with class B on floats instead of integers. Open recursion is a concept that really doesn't show itself anywhere else that I'm aware of. It's for an object to or rather the object definition, the class in most cases, to reference itself. It's normally done with a keyword like this or self, although in certain languages you can name that, whatever you feel like. F sharp works that way, I believe. Real quick, IDA does as well. Although IDA is not class-based, so it's not the class working on that name. But rather the function or procedure as long as it's dispatching will use the parameter name as the self reference. Within information hiding, this was covered slightly before in that classes are a black box. As far as object-oriented programming advocates go, you're supposed to have as little of the eternals exposed as possible, really only exposing what should be worked with. I would argue that this has nothing to do with object-oriented programming and is purely just good design regardless of how you structure the code. Without a technical note, this applies to most languages, not all. Records and structures, basically the same thing, utilize the stack internally in most cases. It depends on the size of them, but they would often be pushed onto a stack and then popped off. Whereas objects are placed into a heap, which while still a very efficient memory structure is not always as efficient as the stack. Don't really worry about that too much, the performance issue present. A good compiler can often place a small object on the stack anyways. So then, sort of the obsession with objects, this is going to get rather hyperbolic, but it's just to demonstrate a point. I will admit one of these slides is a bit of an absurdity fallacy. I'm the one who's being a bit illogical just by making a bit of an absurd claim. It's just sort of for humor, you can say. Even I'm not taking myself too seriously. Come on, there we go. So, like I said, kind of a hyperbolic parallel to two classes would just be to make everything an array. This can be done, sort of. But again, this is mostly just absurd humor. So some reasons why you might not want to go the object-oriented route. Normally, when I would do this as a presentation, I would click on these links and then read through it, assuming there was enough time available. What I'm going to do for this is have these links down in the video description. If you're only going to read one of these, I think the most practical would be this one, from the guys who worked on Legend of Grimrock. They cover some amazing issues with object hierarchies and how they were actually duplicating code that should have never had to have been duplicated and how they fixed it kind of in Legend of Grimrock 2 by taking an alternative approach. This isn't so much to bash object hierarchies because they are useful, just more so to be aware of some of the limitations and when you would not want to pick up an object hierarchy. The rest are a little bit more technical, theoretical, not so much a practical application, but if you can spare the time, I would strongly recommend going through all three of these. So then just leaving you off with something to think about. Implementation inheritance causes the same intertwining and brittleness that have been observed when go-to statements are overused. As a result, object-oriented systems often suffer from complexity and lack of reuse, John Oysterhood. So like always, if you've enjoyed this video, if you found it helpful, informative, please give me a thumbs up. If you like my stuff in general, please follow. It helps me out more than most people will realize. Now have a good one.