Fwd: Alan Kay's Great Mistake [LOOP]

20 views
Skip to first unread message

Fernando Martinez

unread,
Jan 6, 2018, 12:43:07 PM1/6/18
to lapl...@googlegroups.com


En 5 ene. 2018, en 11:00, Avdi Grimm <he...@avdi.codes> escribió:
If there's one thing I've learned in 20 years of software development, it's that good naming is important. Naming things is also, famously, one of the hardest problems in programming.


The power of a name


There is a misconception at the root of the conventional wisdom about object-oriented programming. It's a mistake based on a badly chosen name. For years, I fell prey to this misunderstanding.
 
What is this pervasive misconception? It's the idea that object-oriented programming is principally about objects.

You'd be easily forgiven if that's the idea you had about object-oriented programming. After all, it's right there in the name: Object-oriented.

Here's something Alan Kay had to say about the core value of object-oriented programming:
 
I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea... The big idea is "messaging" - that is what the kernal of Smalltalk/Squeak is all about (and it's something that was never quite completed in our Xerox PARC phase). The Japanese have a small word - ma - for "that which is in between" - perhaps the nearest English equivalent is "interstitial".

The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. Think of the internet - to live, it (a) has to allow many different kinds of ideas and realizations that are beyond any single standard and (b) to allow varying degrees of safe interoperability between these ideas.
(Emphasis mine)

The proper focus when designing an effective object-oriented system is not on the objects. It's on the spaces in between them. It's on how to achieve communication with separation, so that as much as possible, objects can evolve independently.


Four qualities of a good message

It's easy to  fall into the trap of equating a "message" with a "method". But remember what I said in an earlier email: OOP isn't about language technologies. It's about your perspective. And just because an object has a method to be called, doesn't mean you've enabled message-sending semantics in your design.

What makes for a good message definition in object-oriented code? Here are a few suggestions:


Messages are late-bound 


This is a fancy way of saying that only the recipient of a message should get to decide what to do with it.

In some statically typed programming languages such as C++, object methods are early-bound by default (unless prefixed with the virtual keyword). The compiler is able to determine and hard-code exactly which code will be invoked by a method call at the point of the call. In this kind of language, methods are really just glorified procedures, and classes exist more for code organization than for object-orientation.

But even in dynamic languages, it's possible to use methods in an early-bound way. Consider this common idiom in
 
var ring = bell.ring;
// ...later on...
ring();

Here we "pluck off" a method for later use. This is early-binding: rather than send the "ring" message to the bell at the point when we want it to ring, we save off a snapshot of the literal code of the ring method for later direct invocation.

Even without making use of these kinds of direct method calls, it's possible to (unintentionally) treat methods as procedures. We do this when we encode strong assumptions about the outcomes of the messages we send to other objects: e.g., assumptions about the new state those objects will be in after the message is sent. Which brings me to...


Messages are discretionary


If the recipient of a message should get to decide what to do about that message, it follows that one possible options for handling the message is to do nothing. This is the realization behind the Null Object Pattern, a technique which often makes it possible to eliminate numerous conditionals in object-oriented code. (I talk about the Null Object pattern and its generalization, the Special Case Pattern, in my course on Mastering the Object-Oriented Mindset [MOOM]).


Messages are one-way


This is one of the hardest mental transitions to make when [re]learning the object-oriented perspective. If you've worked in Erlang or Elixir at all, you might readily recognize the idea of one-way messages. But in "traditional" OO languages, where messages are implemented essentially as traditional call-and-return functions, it can be very difficult to move away from heavy reliance on return values.

Here's a little-known fact: in one of the early versions of Smalltalk (the language designed by Kay to be object-oriented), message semantics were much closer to what we now call "Actor Model" messaging such as that of Erlang. However, for pragmatic implementation reasons (I believe), Smalltalk messages later became something much more like conventional subroutine calls, including return values.

In a language like Ruby, it's impossible to completely get away from return values and the complications that they introduce. But with the right perspective and coding strategies, you can learn to treat more of your object methods as true one-way messages. "East-Oriented Code" is one attempt to provide a mental framework for this style of coding.


Messages use commoditized formats


The reason messages are so important is that they establish space between objects. But that space isn't real if the information inside the messages requires objects to have a deep understanding of other objects.

For this reason, well-designed messages often pass information in a format that's "commoditized" for easy interchange. For instance, an EmailParser class might use a complex EmailAddress type internally for representing email addresses. But when it sends a message to collaborating object, it might pass the email addresses as simple strings. That way, it isn't requiring other objects to know about the EmailAddress type.

This doesn't mean that every message should pass only "plain old data"---strings, numbers, arrays, etc. Within a given "realm" of your code, certain complex object types may be commoditized. For instance, within the domain models of an ecommerce site, it might be common to pass a homegrown Money type around from object to object. But when communicating with, e.g. the view layer, it may be necessary to "drop down" to a more basic level of commoditized data.


Get the message?

One way I like to sum up the message-sending perspective is with the phrase "notify, don't tell". It's a play on the famous "tell, don't ask" principle. The idea is to think about objects notifying each other of interesting events, information, and requests rather than of trying to force them to do something. I expand on the concept of "notify, don't tell" in the MOOM course.

One ill-chosen name has put the focus on objects for over 40 years. But effective object design doesn't start with objects at all. It starts with messages. Are your objects sending messages?

Happy hacking,

--
Avdi
 
To make sure you keep getting these emails, please add he...@avdi.codes to your address book or whitelist us. Want out of the loop? Unsubscribe.

Our postal address: 141 Deer Run Dr., Maryville, TN 37803, USA
Reply all
Reply to author
Forward
0 new messages