My own definition has always been that an object has state and identity.
I have never considered functions/methods to be a requirement for something to be an object.
My own definition has always been that an object has state and identity.
I have never considered functions/methods to be a requirement for something to be an object.
What the author seems to be saying is that if someone asked you to sell OOP, one way you'd sell it is by mentioning that an object can couple logic and state. That's a distinguishing factor between objects and other data structures.
Depends on the OOP paradigm. This is not always the case.
Functions/methods/actions/operations are just different names for the operations which mutate the state of the object. So, I would argue that they are a necessary attribute of mutable objects.
I have often used data-only objects, and passed them to fixed-context functions.
It's a cheap way to get OO behavior, in non-OO languages.
You have a class/type of objects, and you have a set of functions or operations which are associated with (loosely or tightly) and operate on that type of object.
For example, I would say that file descriptors are a handle to a type of object. They encapsulate the thing that they represent (file, DRM buffer, eventfd, whatever), and some of the functions that operate on them are polymorphic. For example, read, close, ioctl, etc., don't care if the file descriptor is a file, a queue, or whatever.
You use syscalls to interact with file descriptors, but they are just as much object handles.
It separates the functionality from the object. Turns it into an external stimulus to change the state of an object.
I used this pattern, back in the 1990s, to make a C API behave like a C++ API. This was back when every compiler had a different stack convention, and the only one we could rely on, was C.
To be fair, I did have function pointers, in some of the objects, that acted as "poor man's vtables."
I know that the API was still in use, 25 years later.
I think you might be arguing that the object itself does not include the set of functions/methods/operations that act on it, whereas I see them as another attribute of the class/type which is an attribute of the object.
And as for object orientation being less useful in immutable languages, I see it used plenty.
Erlang and haskell both define dictionary types that return new copies of the dictionary on what would normally be mutating function calls. The dictionary's gory details are hidden behind the object's mask, leaving the user free to ignore if it is a hash into an array of arrays, as many dicts used to be and as allows sharing most of the entries between copies of the dict until resizing, or maybe it's actually a balanced tree or just an a-list.
The outer code doesn't need to know because you create and manipulate the dictionary abstractly through helper functions, be they attached via the language or simply exposed while leaving the implementation opaque.
Object orientation will also be used to hide the implementations of files, sockets, and other abstract resources.
Many interfaces throughout the linux kernel use a plain C form of object orientation, a language which is definitely not object oriented on its own, filling out an 'interface' structure with functions to be used for objects originating from a particular area, allowing the kernel to interact abstractly with filesystems via the function pointers in the struct, for example.
Another way to look at it is that property setters (or whatever mechanism is used to directly mutate an object’s sub-data) is not meaningfully different from a method doing the same. You could even call it syntax sugar for the same.
Objects refer to other objects using their (immutable) identity. In turn, resolving identities to objects requires (version) scope which can be in the past or present.
Are you storing the version as part of the object? If so, they’re no longer equal values regardless of identity. If not, what purpose is there in versioning the same value? Even if there is a purpose, are same-value-different-version objects not otherwise interchangeable unless/until some value change does occur?
That’s exactly the point I started with!
> Conversely, two objects can have the same 'value' while having different identities. Values and objects are different beasts.
Agree completely. My point—my only point—was that identity implies mutability. Without mutability, identity distinct from value doesn’t mean anything.