<Make Your Self: In Search for Maxwell's equations...
# share-your-work
m
Make Your Self: In Search for Maxwell's equations of OOP My attempt at growing the smallest object oriented language step by step, let me know what you think!
❤️ 8
j
From a different angle (that would likely displease Kay): https://jackrusher.com/journal/on-object-orientation.html
❤️ 1
m
my main problem with the current take on OO and the idea that OO is just a vtable is that the benefit of real world message passing is that the subject can react to the same message differently depending on context, that's why I put the vtable in the environment 🙂
what does it mean to display? in the functional case there is a module with a function called display and we all call it? in current OO we can say, each object knows how to display itself. ok, fine, but display itself when and where? in a screen? big, small, for edition, read only, for printing, in the body of an email as a preview, when viewed by the owner? someone else? does the object have to know about all possible contexts? does the caller? how do we pass around all the contextual information?
👍 2
👍🏻 1
I can keep ranting 😛
m
it's the last one, I promise!
😆 1
the other side be like: just one more d to cadddddddddr, I need it!
😆 1
k
What is a message reply definition?
I don't follow upLimit and leftLimit. Is it a way to implement lexical vs dynamic scope? Because if it's a way to implement inheritance I don't understand why you'd ever want a limit..
m
> in current OO we can say, each object knows how to display itself. ok, fine, but display itself when and where? in a screen? big, small, for edition, read only, for printing ... I feel like a relational system has a unique advantage here. To me the basic problem is that objects can only have 1 classification (inheritance doesn't really help this). So it might be useful to have a notion of a user, admin-user, student-user, ... I don't want to have a class called
admin-student-user
defined explicitly but.. that type of user might exist. Instead I'd like to just have data globally available, & classification functions/predicates, and operations check the predicates in a prolog-ish way. -- I also think css selector system is another interesting way to tackle the problem of hyper specialized functionality for complex data.
s
What's a good example of a domain where OOP is a burden?
Also OOP is so broad and vague now - we should talk about specific aspects that are associated with OOP. For instance: 1. encapsulation - internal details of objects are hidden and they only allow inspection or modification via a limited set of messages. this is fairly common practice. distributed "services" are just these large objects. even in other programming methods, interfaces come into play. 2. correspondence to domain objects (modeling) - eg a
Window
instance maps to an actual window on the screen, a
User
maps to a user, etc. On one hand you get to map business concepts to code objects. OTOH, you must map business concepts to code objects. 3. inheritance - an occasionally useful implementation pattern for code reuse, i guess. 4. polymorphism - related to encapsulation, allows switching out one object for another because the coupling shape remains the same 5. ...?
I see OOP as a trajectory with many unexplored paths. For instance: • must objects communicate via direct references or can they emit and react to messages in a containing pool (think biological cells, or tuplespaces) • should objects state changes be versioned? can they evolve deterministically by consuming messages? this is idea in the functional style. croquet implements this allowing distributed replicated state. • while state is organized in bundles, control flow is all over the place in oop models. can this be organized differently?
the current oop langs have been backed into a corner also because they exist within the unix process model. for instance, if i define a
class User
I'm really only defining a detail that is very local - within a single unix process. if you zoom out and look at the system with multiple processes and data stores, you see a bajillion
class User
definitions, each defining a partial, local model. to flip this around, if we have an OOP system top to bottom, can we define one system wise
User
while also being able to map these objects to local partial models for pragmatic reasons?
to emphasize that "i see OO everywhere", isn't running a unix program like instantiating a class? the process has hidden internal state, can only be interacted via stdin/out or other apis, you can run multiple instances of the same class (executable) concurrently, etc.
s
“I see OO everywhere”
OOP has some peculiar ways to “hack” into our cognitive system. The way we categorize things when we talk (and think) about them, feels very much like modeling a domain with OOP. And we categorize things all the time. When you casually bring up your neighbor’s dog in a conversation, you say “_dog_”. It would be weird to talk about your neighbor’s mammal. And although possible, if you are super into dogs yourself, you would likely not talk about your neighbor’s cocker spaniel. You pick dog — a natural category that’s not too generic and not too specific, it just feels right. That all happens subconsciously. You don’t really think about it. When modeling a domain we do something very similar. Without much experience, it’s easy to fall into the trap to believe that good natural categories make good classes in OOP. But experienced programmers tend to pick up that modeling domains for programming seems to work better with superordinate categories that are more abstract. Applied to the analogy, programming usually works better if you’d refer to your neighbor’s mammal, or even better to your neighbor’s animal, or even better to your neighbor’s living being, as often as that’s sufficient. That’s how you can reap the benefits of polymorphism best later. You pick the most abstract type class or interface available that models the behavior you want. That, however, is usually much more abstract than what intuitively feels right and is therefore in conflict with your intuitive cognitive categorization. It also requires more abstract thinking when discussing the design with fellow programmers. I think OOP became so popular because it hooks into our cognitive categorization facility so effectively. And it became misunderstood and used “wrongly” because most programmers designed classes to feel like good natural categories that work well in conversation, but then cause problems later because they are too specific for getting the benefits of polymorphism. You can’t really blame them for that. It’s very natural to do exactly that. Literally “_natural_”. Now, dog is a category or class or type. There are many dogs. But when you tell a story about your neighbor’s dog, you use that category as a shorthand to refer to a very specific thing that is unique. Unless your neighbor has several dogs, there is only one instance (and if your neighbor has several dogs, you would’ve qualified it more to refer to one of them). It’s easy to mix up what we’re doing here: We use an abstract category (class) to refer to a specific thing (instance). Human language is super ambiguous, but we usually get the level of abstraction right so we can understand each other. And we don’t really think about that distinction between a category and a unique thing either. We (usually) tend to just know what we mean. In programming we need to be more precise. The colloquial understanding of OOP is that behavior is modeled in classes (because we want to reuse it), while state is modeled in objects (because we need to distinguish different instances). The confusion with what Alan Kay really meant comes from that. Because in Smalltalk both behavior and state are modeled in objects, and it is kind of understandable why he called it “object-oriented” and why he dislikes classes. And message passing was so important because that was the universal interface for any kind of object to interact with any other kind of object. Message passing was the most abstract behavior that applied to all state — maximally efficient polymorphism, if you will. Class-focused OOP happens, pretty much naturally, if we just apply our unreflected naive understanding of how we categorize things and model our domains like that. I haven’t worked out if all that makes OOP a good or bad approach to modeling domains. It’s obviously beneficial to hook into stuff that comes easy to us, but then it seems as if in this case we get lead down the wrong path too easily and what we need for good design is somewhat opposed to what feels right intuitively. But then if you’re aware of that, you can make it work quite well. 🤔
💯 3
e
Do we actually classify to concrete things? Like 'dog' or do we (also?) classify to behaviour? The thing that has dog-like behaviour. The barking of the neighbours dog (which I btw refer to as 'Sarah' instead of 'dog' when talking to the neighbour) is the topic of a short interaction. That could just as well have been an interaction about one of their sons, which also barks (i.e. makes loud noises) at times. I'm trying to move towards more behaviour-driven classifications and a model in which objects can have multiple behaviours. This would be dynamic, adding or removing behaviour based on the context. So not a static class hierarchy. Objects would receive messages (like in an inbox) and decide what to do with it. The default behaviour would be to execute a method with the same name (aka #selector, yup Smalltalk-like).