3 ms·
Doesn't OOP have the ontological problem: Does the knife cut the cheese, or does the cheese get cut by the knife? Formally: Is it knife.cut(cheese) or cheese.g
by man-and-laptop 8y ago
Doesn't OOP have the ontological problem:
Does the knife cut the cheese, or does the cheese get cut by the knife? Formally: Is it knife.cut(cheese) or cheese.getCutBy(knife)? And why is the first argument (knife in the first instance or cheese in the second) special? Maybe Alan Kay means something different and less overtly flawed when he talks about OOP.
- mercer 8y agoI could be entirely off here, but it seems to me this problem is less present when you send messages instead of call methods. From the perspective of sending messages, the solution is that the knife object/actor sends a message to the cheese object/actor that it wants to cut it. the cheese can then respond to that message by changing its state to 'cut', or perhaps by sending a message back to the knife that it's not sharp enough for this particular chunk of cheese, and that the cheese remains in an uncut state. The knife actor/object could then decide to break, or sharpen itself, or whatever. I haven't given this much thought yet though, so I'd love to hear how I'm all wrong about this! EDIT: I guess this comment says something similar: https://news.ycombinator.com/item?id=18333652 https://news.ycombinator.com/item?id=18333652
- tonyg 8y agoWhere is the state? What changes in response to the send? Here, it'd be the cheese, so it'd make sense to have the cheese be the receiver; but a real answer comes from moving further toward the Actor perspective. Given a distributed system with message passing, how do you choose to allocate locations to items of mutable state? That choice gives you your answer. All single-receiver systems have a problem when faced with multiple otherwise-independent pieces of state that have to change in response to a given combination. You end up encoding various kinds of transaction to keep every member of the group on the same page. Multiple-dispatch systems don't have that problem, but the tradeoff is that they're no longer message passing: all the "recipients" of a "message" live logically in the "same" location for the purposes of handling a given invocation, and if they're actually physically separated, the language implementer has to do the job of providing the illusion (e.g. via transactions) that they're in the same place.
- eadmund 8y agoNot all OOP, just the normal sort. With CLOS, you'd just define a generic function like this: (defmethod cut ((subject knife) (object cheese)) …)
- Someone 8y agoThe butler did it :-) theButler.cut(cheese using: knife) Seriously: I think every programming language has that problem. If cheese and knife are arguments to a function, one of them comes before the other. It doesn’t matter much whether there’s a parenthesis, a comma or whitespace between them. And yes, that includes esoteric programming languages that inflect variable names to indicate what’s the subject and what the object of an action (example: http://users.monash.edu/~damian/papers/HTML/Perligata.html http://users.monash.edu/~damian/papers/HTML/Perligata.html) They make some words special not by position, but by inflecting them differently.
- derefr 8y ago"Objects" have nothing to do with taxonomies, or where you put your state. Objects are only an answer to the question: where does the computation that updates the state live? Or, to put that another way: objects are minimal abstract computers. Picture the same situation, except instead of objects, we've got computers. Three, in fact. One that's running a "knife service", one running a "cheese service", and one that's an RDBMS. To cut the cheese in this Service-Oriented Architecture, what do you do? Well, probably, you start by getting a cheese handle from the cheese service, and getting a knife handle from the knife service. Then, very likely, you're going to tell the knife service—passing the knife handle and the cheese handle—to cut the cheese. And the knife service is in turn going to talk to the cheese service—passing the cheese handle—telling it that the cheese should get cut, and specifying what the knife wants to do. If the cheese succeeds in getting cut, then it returns updated cheese to the knife, which returns {success, updated cheese} to you. Why all that? Because: • Only the knife service contains the code—the business logic—to know how knives work, so only the knife can construct a description of the precise way that the knife is going to try to cut cheese. • And only the cheese service contains the code—the business logic—to know what cheese is like as a material, so only the cheese can evaluate the attempt by the knife to cut it. OOP is just like SOA, except that the fact of what "service" (i.e. class) you should talk to about a given object-handle is encapsulated within the object, and is potentially even a mutable property of that object. (Maybe cutting your cheese with a hot knife results in your cheese-handle mutating into a raclette-handle.) Also note that at no point did I say where the state for anything is. It's in the RDBMS, maybe. Or maybe the durable state for all knives is inside the knife service, and the durable state for all cheeses is inside the cheese service. It's kind of irrelevant. (That's another thing about objects: they entirely encapsulate their state, so it doesn't matter where it is. This allows for e.g. distributed object frameworks where you have local objects that stand in as proxies for remote objects somewhere else. Just like in an SOA, you can have network proxies that stand in for services somewhere else.)