4 ms·
I think the modern definition of "object-oriented language" is skewed too much in the direction of "what C++ is doing". The OOP paradigm, as far as I remember,
by bheadmaster 3y ago
I think the modern definition of "object-oriented language" is skewed too much in the direction of "what C++ is doing".
The OOP paradigm, as far as I remember, relies on the four pillars:
- encapsulation
- abstraction
- inheritance
- polymorphism
All of which exist in Go (encapsulation: structs; abstraction: interfaces; inheritance: struct embedding; polymorphism: interfaces). Nobody said that inheritance must be polymorphic, like it is in C++ with virtual methods. Nobody said we must have the "class Class { members... }" syntax like we have with C++. Those are all just implementation details.
Go is a perfectly good OOP programming language, it just differs from C++, so C++-ians who can't see anything beyond the syntax claim it's not OOP.
- JonChesterfield 3y agoWhat would inheritance without polymorphism be?
- bheadmaster 3y agoI don't know, and I never mentioned inheritance without polymorphism, so I don't see how its relevant. Go supports both inheritance and polymorphism. It just doesn't have polymorphic inheritance, which doesn't really bring you any new abilities that polymorphism and inheritance themselves didn't bring. Please see this comment for an example of Go's polymorphism and inheritance working together to do what you would need virtual methods for in C++: https://news.ycombinator.com/item?id=35784598 https://news.ycombinator.com/item?id=35784598
- JonChesterfield 3y ago> Nobody said that inheritance must be polymorphic Polymorphim normally means dispatch based on type of the first argument to a function, sometimes called a method. Occasionally dispatch based on type of all arguments to a function. Inheritance is a means of deriving types from other types. That's usually done as a means of controlling dispatch via the above polymorphism. I don't know of a different motive for inheritance. You claimed inheritance doesn't need to be polymorphic, as quoted above, so I hoped you had a different perspective on it.
- bheadmaster 3y ago> I don't know of a different motive for inheritance. Code reuse? You have a base class that does a bunch of stuff, and you want to add a single thing. If there wasn't any motive for inheritance without polymorphism, then all methods in C++ would be virtual, wouldn't they?
- nyanpasu64 3y agoSomething close would be C++ private base classes with non-virtual base methods statically invoked by child methods? For example, some C++ types like std::string and glibc's std::vector/shared_ptr/refcounts perform inheritance of base classes (some public, some private implementation details), and call virtual or statically dispatched methods on base classes.
- gpderetta 3y agoinheritance is not polymorphic in C++. Virtual methods are opt-in. edit: also by experience, the intersection of all common definitions of OO is the empty set. At this point I think it is best to leave the OO definition only for those languages that self define as such (which would btw exclude C++) and it is more of a philosophy of software design than an actual set of features.
- bheadmaster 3y ago> inheritance is not polymorphic in C++. Virtual methods are opt-in. Exactly, if you want polymorphism in C++, you have to drag in inheritance too. You can't have the former without the latter. In Go, you can have polymorphism through interfaces without ever embedding a single struct, so that would make Go more OOP than C++.
- kazinator 3y agoInterfaces are useless in the context of OOP because they don't bring in implementation (or anything else). The beauty of inheritance is implementation reuse. In a proper Alan-Kay-Blessed OOP language, the "interface" has no role. Why? Because there is extermely late binding everywhere. What that means is that if we want an object to be substitutable wherever a Duck is needed, we just need to make it quack like a Duck. It doesn't have to inherit anything. Interface inheritance is just syntax: a static type system imposed into OOP, which lets you do type checks. Oh! That object cannot be used here; though it quacks like a Duck, it doesn't inherit DuckInterface. Please add DuckInterface, then fix errors (if any) and try again. Now inheritance is actually useful even when we have the above True Scotsman's Late Binding OOP that doesn't impose static interface cruft on us. Because: 1. It lets you use implementation. Say that quacking like a duck is a complex set of behaviors. Let the specialists develop (and maintain) DuckBase: you just inherit that (and pull in updates once in a while). 2. It gives you a real instance-of dynamic relationship: your object can be asked "are you a duck" at the dynamic type level, and the type system will assure the caller, that "yes". You can't get that if your duck behavior is coming by delegation to an object contained in your DuckLike by composition. Also, only multiple inheritance is the real deal; single is seriously crippled.
- kazinator 3y ago> Nobody said that inheritance must be polymorphic. The derived object has to be substitutable for the base object. If not, then you don't have the late binding needed for OOP. I would say that the third pillar ther should be "multiple inheritance". Single inheritance is fake/garbage inheritance, not suitable for full blown OOP. If you just have single inheritance, and you've already committed a class to an inheritance base (out of some necessity), then you're screwed if you suddenly need an object of that type to be an "instance of" something else.
- kaba0 3y agoMultiple inheritance has grades. It’s perfectly fine to have single class inheritance and multiple interface one for example.
- kazinator 3y agoYes. If you don't have it, that's an F grade. Ruby modules get a D, and Java interfaces a C-. C++ gets a D- with its base classes having to be declared "virtual" nonsense in order that your object isn't a Duck in four different ways due to diamonds in the inheritance lattice.
- bheadmaster 3y ago> The derived object has to be substitutable for the base object That's polymorphism, and isn't part of the definition of inheritance. Otherwise, inheritance and polymorphism wouldn't be separate concepts.
- usrusr 3y agoAt this point I feel tempted to simply draw the line between languages that have syntax to pull the first parameter of a function to the left side of the function name and languages that don't. All features beyond that are variations of the theme that should better be spelled out in full, trying to claim them as defining properties of OOP reeks of self-importance. And even if you take the liberty of declaring that a more general definition paired with a more specific one, the more specific one should not so much distinguish on language features but on the standard lib: is your typical stdlib call something scoped to an object (subject parameter pulled to the left) or is it some global name or with just a namespace on the left? mystring.length() vs strlen(mystring)? Most languages these days have both, but if the "strlen" form is the dominant one no amount of OO features should allow you to call yourself OOP without twitching. And if object.method() is the dominant form, how you got there is just details. It feels embarrassingly lame to stay that close to the syntactic surface, but the dogmatic deep-dives really don't help.