• The cover of the 'Perl Hacks' book
  • The cover of the 'Beginning Perl' book
  • An image of Curtis Poe, holding some electronic equipment in front of his face.

Alan Kay and OO Programming

minute read



Find me on ... Tags

Update: Many peoplea argue that messaging is flawed because your software breaks if you don't get a response. I wrote a new article, begging to differ.

I'm not going to link to the thread which set me off on this topic because there's no need to embarrass the people who say things like ...

Programming existed. Objects existed. Then [Alan] Kay contributed "-oriented" to the term "object-oriented programming" and the world went wild, but why?

Or another person, objecting to Kay's criticism of "modern" OO programming:

"It's different than what I already know so it's wrong." This kind of thinking is why I quit CS major, chose to not pursue a career in programming, and haven't looked back.

This was largely in response to Alan Kay's famous 1997 OOPSLA keynote which is worth watching in its entirety.

There's much more in that thread, and while some understood what Kay was trying to say, many others seemed unaware of Kay's background and acted as if he was some grumpy old dude who just graduated from a Rails Bootcamp.

This is Dr. Alan Kay we're talking about! He doesn't have random opinions about "objects", he invented the word back in the 60s . He saw what was happening in the programming world and was helping to craft many of these ideas, so he created a word to make these ideas easier to talk about.

And he's still bitter about choosing that word. It made people focus on the implementation rather than the behavior and it's all been downhill from there. Or as Dr. Kay put it "I invented the term Object-Oriented, and I can tell you I did not have C++ in mind."

Today, most developers think OOP is about classes and inheritance. Some of the bright ones pipe up about encapsulation and polymorphism, but that's about it. class Dog isa Mammal {...} has won.

But for Dr. Kay, he states that OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. Why? Well, part of his background was cell biology and when he did the math on their computational power, he realized that while software routinely has trouble scaling, cells can easily coordinate and scale by a factor of over a trillion, creating some of the most fantastically complex things in existence, capable of correcting their own errors. By comparison, the most sophisticated computer software programs are slow, tiny, bugfests. Kay's conception of OOP starts with a single question: how can we get our software to match this scalability?

Isolation

First, let's discuss isolation. This is a shorter term than "local retention and protection and hiding of state-process".

The interior of a cell is messy and confusing, but the cell membrance wraps this up in a tidy package, hiding the internal details. It's estimated that around 50 to 70 billion cells die in your body every day. But you don't. Could your software keep running if you had millions of exceptions being thrown every minute? I doubt it.

You not dying when your cells die isn't encapsulation; it's isolation. Consider the following (awful) example:

class MyExample:
    def reciprocal(self, num):
        return  1.0/num

example = MyExample()
print example.reciprocal(4);
print example.reciprocal(0);

In the above code, we've encapsulated the reciprocal equation in the class, but then ...

0.25
Traceback (most recent call last):
  File "class.py", line 7, in <module>
    print example.reciprocal(0);
  File "class.py", line 3, in reciprocal
    return  1.0/num
ZeroDivisionError: float division by zero

The object dies, as does the code which contained it. This is the antithesis of what Dr. Kay is trying to get us to understand.

If you think of Web browsers and servers as objects, however, we see something closer to his vision. If your browser crashed every time a web server crashed or was otherwise unavailable, Microsoft IIS would never have reached 2.0.

Now that we sort of understand a core idea of Kay's, Lets take it further. Kay points out that from the early days of Arpanet in the 60s, to the time of his OOPSLA keynote in 1997, Arpanet had grown roughly 100 million times the size of what it was. And it didn't have to be repeatedly taken down for maintenance every time we wanted to extend it. The internet, today, is sometimes cited by Kay as the only working example of his OO model.

Extreme Late Binding

Another key point is his arguing for extreme late-binding. What does that mean? Well, consider this code:

my $order = OrderFactory->fetch(%order_args);
my $invoice = $order->invoice;

If you have multiple "order" classes, you may not know which class you are dealing with, so you can't know, at compile time which invoice method you're calling. OOP languages generally don't select (bind) the method (invoice) for the invocant ($order) until run time. Otherwise, polymorphism can't work.

But what's extreme late binding? Does the invoice method exist? In a language like Java, that code won't even compile if the method doesn't exist. It might even be dead code that is never called, but you can't compile it if that method isn't there. That's because Java at least checks to ensure that the method exists and can be called.

For many dynamic languages, such as Perl (I ♥ Perl), there's no compilation problem at all because we don't bind the method to the invocant until that code is executed, but you might get a panicked 2AM call that your batch process has failed ... because you might have encapsulation, but not isolation. Oops. . This is "extreme" late binding with virtually no checks (other than syntax) performed until runtime.

Binding can also refer to binding a variable type to data. . While this is a grotesque oversimplification of a complex argument, one way of looking at the difference between static and dynamic languages is that static languages such as Java often bind the data type to the variable (in other words, the named container of the data), meaning that you can never assign a different type to that variable, while dynamic languages such as Perl bind the data type to the data itself, meaning that the data knows about its type, but the variable often does not. The latter is late binding because you often cannot infer, from static analysis, the data types at compile time.

Extreme late-binding is important because Kay argues that it permits you to not commit too early to the "one true way" of solving an issue (and thus makes it easier to change those decisions), but can also allow you to build systems that you can change while they are still running! When was the last time you changed the behavior of a program and didn't have to stop it and restart it, often waiting hours for a complex recompilation? If you've worked with Smalltalk or Erlang you've probably had this pleasure, but most of the rest of us are still struggling with the hell of Makefiles and scheduled downtimes.

Messaging

We can kind of see the isolation and late-binding, but it's messaging where Kay's message seems to fall down for most, even though he's quite insistent that it's the most important thing there is in OOP. In essence, objects should be able to announce that they did things and other objects can ignore them or say "hey, that's cool. Here's what I did in response."

But that doesn't really get to the core concept of messaging and frankly, this is the one area where I think Kay has been a touch vague, largely because many developers think that ideas are nice, but they want to see an implementation or proof of concept. In Kay's world. every object is almost like an entire computer, not just a unique area of responsibility, and each object can receive messages and figure out whether or not it knows how to deal with them.

In other words, you don't execute code by calling it by name: you send some data (a message) to an object and it figures out which code, if any, to execute in response. In fact, this can improve your isolation because the receiver is free to ignore any messages it doesn't understand. It's a paradigm most are not familiar with, but it's powerful.

There's a lot more to be said about this, but I'll stop and instead direct you to this article, written by Alan Kay, about The Early History of Smalltalk . I actually found myself giddy reading that, getting a glimpse into the Cambrian explosion of computing ideas which happened during the 60s and 70s. Sadly, computing, as with evolution, left that explosive era with powerful tools, but fewer ideas. Functional programming is slowly gaining more converts, logic programming is largely ignored , but most programming today is procedural or class-based OOP. But Kay's ideas of what he intended for OOP are still with us. You can check out Erlang and discover a marvelous programming language where code is isolated, late-binding, and passes messages around. And what do you get for that?

  • Extremely fault-tolerant code
  • High availability
  • Code whose behavior can be changed while the software is still running

That last point is a killer feature for many companies. The Erlang syntax and behavior is strange for many developers (it looks a lot like Prolog with the solver removed), if you have millions of customers counting on your service to always be there, Erlang is a powerful option.

OOP Today

Kay argues (correctly, IMHO), that the computer revolution hasn't happened yet because while our bodies are massively scalable meat computers, our silicon computers generally don't scale in the slightest. This isn't just because silicon is slow; it's because of things like print customers.fetch(customer_id).last_name not actually having a last_name method, throwing an exception (assuming it compiled in the first place) and programmers getting frantic late-night calls to bring the batch system back up. The only real upside is that it offers job security.

Sadly, this is where most of us are today. And would-be programmers get silly lectures telling them that class Motorcycle extends Vehicle, the instructor (isa Person) gets flustered explaining for the nth time the difference between a class and an instance, while a student (isa Person) in the back is noticing that a bicycle looks an awful lot like a motorcycle and the code she's looking at doesn't seem to account for this.

So class-based OO has won, even with its limitations, arguments over inheritance versus composition, static versus dynamic typing, and programmers arguing whether "objects" are data with behaviors attached or vice versa. So this sometimes puts me in an awkward situation when someone asks me what objects are since the myriad disagreements are strong, and valid.

I sort of punt on this, taking a "meta view" of what we're trying to accomplish when we write software. So I'll finish up by offering my view on objects, with an extended quote from my book Beginning Perl .


ÆVAR THE PERSONAL SHOPPER

Many books have been written about OOP and even among experts, there is often disagreement about what OOP is. Many programmers have tried to explain OOP and leave the programmer confused. A case in point is the classic “An object is a data structure with behaviors attached to it.” Although that’s correct, that’s also an awful description and tells you almost nothing you need to know, so instead of giving you a textbook definition, we’re going to tell you a story.

You’re an awfully busy person and have little free time but plenty of disposable income, so you’ve decided to hire a personal shopper. His name is Ævar (any resemblance to reviewers of this book, living or dead, is purely coincidental) and he’s friendly, flamboyant, and most of all, cheap.

Because Ævar is new to both your city and the job, you have to tell him carefully how much money he can spend, exactly what quality of products you want, and where to buy them. You may even have to tell him which route to drive to pick up the goods and how to invoice you.

That, in essence, is procedural code and that’s what you’ve been doing up to now. You’ve been carefully telling the computer every step of the way what to do.

After a few months of explaining every little detail, Ævar gets upset and says, “þegiðu maður, ég veit alveg hvað ég er að gera” (Icelandic for “Shut up dude; I know what I’m doing”). And he does. He knows what you like and where to get it. He’s become an expert. In OO terms, you might now be doing this:

my $aevar = Shopper::Personal->new({
    name   => 'Ævar',
    budget => 100
});
$aevar->buy(@list_of_things_to_buy);
my $invoice = $aevar->get_invoice;

You’re no longer telling Ævar every little step he needs to take to get your shopping done. He’s an expert, and he has all the knowledge needed to do your shopping for you and present you with the bill.


And that's it. Objects are simply experts. You tell them what you need and they get it done. Forget all of the handwaving about blueprints or "data with behaviors." Those are implementation details. And once you start thinking about objects as simply experts about a particular problem domain, OOP becomes much easier.

Please leave a comment below!



If you'd like top-notch consulting or training, email me and let's discuss how I can help you. Read my hire me page to learn more about my background.


Copyright © 2018-2024 by Curtis “Ovid” Poe.