--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/8ebcb5cc-1282-4ad1-8b73-4fa51236cca8n%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/CAJ7XQb4MECMNS%3DNqvN_7jY_JTmNz8eAfbB9h9t%2BtOM-WraLKKg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/CAJ7XQb4MECMNS%3DNqvN_7jY_JTmNz8eAfbB9h9t%2BtOM-WraLKKg%40mail.gmail.com.
On 16 Apr 2024, at 01.53, Raoul Duke <rao...@gmail.com> wrote:
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/CAJ7XQb4MECMNS%3DNqvN_7jY_JTmNz8eAfbB9h9t%2BtOM-WraLKKg%40mail.gmail.com.
Thanks Cope, I think the familiarity argument makes a lot of
sense. I'd like to pivot now to talking about this problem in
general and not only as it applies to the trygve language. (I can
see how implementing prototypes, even if we all agreed they were
better than classes in some way, could be a bit of a distraction
from the main point.)
Like you, I don't think having to declare a singleton for a class is a big deal. To me, the most compelling argument for prototypes (based on my own programming experience) is the ability to use traits/mixins that can reflect the changes to an object's data needs over time. Promoters of prototype-based languages or languages with traits have long talked about the benefits of using traits to define behavior that can be added to different types of objects as needed, but I think those who have used DCI realize that this sort of free-for-all is far less desirable than DCI contexts.
However, I think there's still such a thing as a "data trait,"
and I don't think classic DCI fully solves that problem. As an
example, I think it's pretty common to store some common
properties that apply to all users (or even all people—since the
system may also need to represent people who never log into the
system)—name, address, email, password, etc—and also store data
related to the user's role, or multiple roles at the same time.
Roles like Administrator, Instructor, Parent, Student, Customer,
etc.
I have been slowly reading Meilir Page-Jones's book Fundamentals of Object-Oriented Design in UML (originally titled "What every programmer should know about object-oriented design"). I'm mainly reading it for historical context, to understand classic OOP thinking—both its best parts and its faults. It includes an interesting example of a fictional dog-tracking application that needs to record which person owns which dogs, and also how many dogs each person owns. This is a simple example of what I'm talking about: a person can become a dog owner at any time, and they could also cease to be a dog owner, and it would be best not to have to throw out the Person object or change its identity just for that reason. The relevant data property here is numOfDogsOwned. Based on the example in the book, if we were to pretend that every person is always a dog owner, it would look something like this if represented as a class:
class DogOwner {
name: PersonalName
address: StreetAddress
numOfDogsOwned: Integer
}
The author points out a flaw in all the OOP languages that were popular at the time: "They don't support an object's ability to acquire or lose class membership or to hold multiple class membership (apart from that implied by the inheritance hierarchy) at one time. A design approach that provides such abilities [meaning the class and inheritance-based designs proposed in the book] is a work-around for an object-oriented language flaw."
Prototype-based languages don't suffer from this flaw. And if I
understand it correctly, the Self language goes a step further by
allowing an object to have more than one parent slot that
automatically delegates to a prototype, meaning you can have not
only multiple inheritance of data properties but also dynamic
multiple inheritance of such properties (i.e., add and remove the
prototypes you need at run-time as needed). I'm not claiming it's
a silver bullet, but it certainly seems like a nice feature to
have.
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/092EB597-9187-4A26-B76C-EE2AB962A4D5%40gmail.com.
dynamism of any kind is very very dangerous deal with the devil in my mind wrt things like maintenance and robust extensibility.
I get your point, but I think that any move from class-oriented to object-oriented inherently means more dynamism—but it doesn't have to mean completely giving up type safety. And this is all in the interest of being more faithful to our mental models and the fact that the real world (and real systems) aren't static. I think DCI accomplishes this quite well with role-object contracts. And even if you have dynamic mixins for your data objects, those contracts would ensure that at least you would be failing early if there were an incorrect typecast or something prior to when you pass it in to a DCI context.
Another factor to consider: in the case of data objects, removing the trait when it's no longer needed is arguably less important than it is for DCI roles. (In the case of DCI roles, the chance of name conflicts or just confusion if the role methods stick around longer than they should is probably higher.) So if we only really care about being able to add data traits to a new or existing instance, the problem becomes a bit simpler and some existing statically-typed languages (i.e. the ones with traits features) aren't so far off from this.
Maybe it would even be preferable not to ever remove data traits:
in the dog-owner example, it doesn't matter if you delete the numDogsOwned
property when it's no longer needed (assuming it was already
stored in a database somewhere if it needs to be archived) because
it would always be zero at that point. But I'm guessing there are
other cases where deleting properties probably wouldn't be the
best option.
On 23 Apr 2024, at 14.43, Matthew Browne <mbro...@gmail.com> wrote:I get your point, but I think that any move from class-oriented to object-oriented inherently means more dynamism—but it doesn't have to mean completely giving up type safety. And this is all in the interest of being more faithful to our mental models and the fact that the real world (and real systems) aren't static. I think DCI accomplishes this quite well with role-object contracts.
On 22 Apr 2024, at 01.02, Matthew Browne <mbro...@gmail.com> wrote:The relevant data property here is numOfDogsOwned. Based on the example in the book, if we were to pretend that every person is always a dog owner, it would look something like this if represented as a class:
class DogOwner {
name: PersonalName
address: StreetAddress
numOfDogsOwned: Integer
}
To me there is a fundamental flaw in reasoning here in that numOfDogsOwned is a data object or that it represents a primitive value. To me it is an iteration over a database counting items with given properties and/or relationships. It’s like a balance in a bank account: it’s not data, but rather a value produced by a computation.
These are all valid points, but I think the author just intended
it to be a simple example for a simple fictional system—probably
unrealistically simple.
So let's use a different example: suppose we need to keep track of a university student's level (first year of college, second year, etc; this property could alternatively be named year if that's not too confusing since it's not the calendar year). Additional requirements: the Student type needs to inherit from a base User type, and we want Student to be a trait rather than a class, because of situations like this: perhaps someone is already in the system as a Teacher but then they decide to enroll in a class so they become a Student as well.
I think we now have a technical problem to solve that's very
similar to what I described for the dog-owner example, which isn't
merely a result of a flawed design / mental model.