My personal definition of OO has been backed down to directly connecting some concept of "method" to a data structure, and some form of polymorphism of those methods depending on what data structure you pass in to some function/method. You may note this is incredibly weak, but it does have the virtue of usefully distinguishing between two sets of languages, and that those two sets will have real differences in how you program them. Beyond that it's hard to create a definition of OO that has the second property; you may be able to split the world into "languages that implement OO visibility rules (private, protected, public) and those that don't", but you'll fail the second criterion, in that languages that just leave everything public aren't meaningfully different to program in than ones that implement the visibility rules.
I could create several different sets of "OO principles", which wouldn't be mutually exclusive necessarily but certainly would be distinguishable. Especially the distinction between the silly principle that OO objects should somehow reflect real-world entities, which was the major failure in 1980s/1990s OO principles and has, mercifully, all but died in the modern era but most certainly was at one point an "OO principle", and any of the several sets of OO principles I could name that actually function in the real world.
OO Programming 101, OO principles: encapsulation, abstraction, inheritance, polymorphism, SOLID.
Whatever a specific language adheres to and how is beside the point.
To wit, encapsulation and abstraction existed outside of OOP (for example, Modula had it before), inheritance is not a necessary feature for OOP (Self doesn't have it), and the O in SOLID doesn't apply to Smalltalk and Self.
Alan Kay considers that inheritance and polymorphism are not essential, fine. He does consider encapsulation essential, though. Specific languages have their own take, fine.
The point being is that there are well-known OO principles. Claiming otherwise is either disingenuous or ignorant.
It was in the 70s, and his description that I quoted is from the 2000s.
> Alan Kay considers that inheritance and polymorphism are not essential, fine.
Polymorphism is a logical outcome of his requirements. So in a purely logical sense it is essential, although I imagine that saying that might be a little bit like saying that CO2 is essential for a campfire (as in that you can't get a campfire without emitting CO2, even though that is strictly a matter of consequences).
> He does consider encapsulation essential, though.
Yes, because biological cells are encapsulated.
> there are well-known OO principles. Claiming otherwise is either disingenuous or ignorant.
There surely are some "well-known principles" but whether the "known" in that phrase has the same meaning as in "knowledge" (justified true belief at a first approximation) seems debatable.
I'm sorry but this is getting surreal.
I named the standard OO principles and concepts which are very much valid and alive today, though of course how they are applied (or if they are applied at all) varies from language to language. Claiming otherwise is absurd. If anything this whole article and thread show that too many people are confused by the concepts of OO principles (if they know what that means at all), programming languages (that may or may not implement some of these principles), design practices/patterns (how to come up with a model of objects): these are all different things. Certainly selecting objects that reflect real-life entities is not an OO principle, for instance, but rather a design practice (good or bad, it depends).
In my team we do C exclusively and follow OO principles as much as practical. Any software engineer worth their salt has a good idea of what that means.
C, for all its faults, has encapsulation at a module level: any functions you don't define in your header file aren't exported and are thus private. Go and rust do the same thing.
Abstraction is even more common. Functions are abstractions. And any language with typeclasses (like haskell) or function overriding (like Julia) uses a form of polymorphism
Really, the only essentially object-oriented things here are inheritance and (by extension) inheritance-based polymorphism.
No language that supports memory access for the entire address space of the currently running program can ever support something like encapsulation: you can pass pointers to objects and functions outside the currently running module, or you could somehow derive this info from outside the module and so access functions and objects that were not declared in header files. Thus the language cannot give you the isolation guarantees that memory managed languages can. What it can do, is put up some roadblocks or barriers that require effort to cross. But there is a big difference between correctness guarantees and roadblocks.
There really is a qualitative change when you are working in a memory managed language as that allows the language to assign fine grained control over which memory addresses are available to which data structures, which is something that you cannot do with C.
I mean, that is the discussion we were having. We weren't talking about language VMs.
You interpreted that as meaning memory isolation for some reason (even though plenty of clearly-OOP languages do not implement that), and when someone asked you how that definition of encapsulation squared with the fact that C++ is generally considered object-oriented, you said you didn't want to have that conversation.
It's not hard to follow and it didn't trip anyone up; you just changed the subject out of nowhere and for no discernible reason by injecting a contextually-inappropriate definition of "encapsulation."
Or in other terms, without an implementation, OOP isn't even usable, it isn't even real. Just maybe a desirable ideal somewhere.
That's clearly not the case. C obviously does not enforce encapsulation, and it's extremely common for devs not to follow this principle, in fact it's pretty much the default not to and it takes discipline to enforce it.
"Encapsulation at module level", as you wrote earlier, is not encapsulation. If you implement your object as a struct (which is really what objects are) then encapsulation means not accessing the content of that struct/object directly.
I also gave the examples of rust and go, which have private struct fields but are not really object-oriented, and encapsulate at the module level. Point is, OOP does not by any stretch have a monopoly on encapsulation, and OOP should not be defined in terms of it.
Encapsulation in the context of OOP means effectively hiding the data within an object from the external world and not allowing direct access to these data.
OOP may not have a monopoly on this but this is indeed a defining feature of OOP (which you know very well if you ever took a programming 101 course): You may have encapsulation without OOP, but in OOP you must have encapsulation. It's not OOP if there's no encapsulation.
Encapsulation is not something enforced by C (access to struct's fields is free for all). And this is not a principle generally followed in C code (most C code does directly access fields within whatever struct). Hence my rebuke to your claim of the contrary.
Now, obviously this can be done in C, this is a matter of choice. OOP can be done in any language. There seems to be confusion in many comments between OOP and specific languages.
Lastly OOP are a set of principles. Principles are rarely followed in their entirety and indeed many languages pick and choose which, if any, principles they implement and how they implement them. It's the same when 'practising' OOP in a language where you have to do everything "by hand", like C: You pick and choose as needed.
I'm out.
Setting aside the fact that any 101 course is necessarily reductive and inaccurate, "encapsulation + abstraction + polymorphism + inheritance = OOP" is something that gets regurgitated a lot without ever really being argued in favour of.
Since the first 3 of those 4 points are not at all limited to OOP, it really doesn't make sense for them to constitute ¾ of the definition. Are they really OOP principles if basically every modern language follows them? And now that we largely agree composition > inheritance, OOP often ignores that fourth principle too.
I know you hate C as an example here, so let's use rust instead. If a rust codebase can exercise encapsulation, polymorphism, and "abstraction" (still the vaguest and weakest criterion imo), and OOP code is discouraged now from using inheritance anyway, what stops it from being OOP? Most of the rust I've seen hasn't fit with any conventional notion of OOP, but it still technically matches the definition. Doesn't that make it a bad definition?
There are OO principles, which are indeed well-known, and each OO language has its own take on how to implement them.
It's not even needed to use an OO language to follow OO design principles. My day job is pure C and we follow OO principles as much as practical.