Alan Kay on the misunderstanding of OOP
lists.squeakfoundation.org
lists.squeakfoundation.org
You're right that message passing is a different way of looking at things; but obviously it's something different to method calls. Delegation, for one thing, is much easier with message passing, as are other strategies, like default implementations, remoting (never mind how poorly RPC scales), etc. On the other hand, getting two objects to communicate over a private channel can be more awkward, as they need to share pre-arranged references, rather than simply being friends / package / internal visibility, or similar visibility override.
They thought I meant an MQ type message, and were completely unfamiliar with the concept of message passing.
It pains me when people spend a fair amount of time coding Ruby, and then encounter metaprogamming and dynamic method invocation, and because of their wrong preconceptions they think it's deep, dark, super-genius hackery.
Unfortunately it gets clumsy to always say, "passes the message 'foo'" instead of "calls 'foo'", but if you can make the point early and toss in some reminders along the way the idea may stick.
Which is a crippled version of C++'s Object Model.
About which Alan Kay said: 'Actually I made up the term "object-oriented", and I can tell you I did not have C++ in mind.'
http://video.google.com/videoplay?docid=-2950949730059754521
I'll read the whole thing when I'm done with the other link (which is a really long and very interesting piece).
Getter and setter methods on objects are like OK and Cancel buttons in dialogs. Just because it's uniform industry "best practice" doesn't make it not completely retarded and obscurantist.
Edit: If this is any indication then I'm prepared to declare "message passing" a heisenterm, with no formal definition across all contexts:
http://stackoverflow.com/questions/43777/method-vs-message-v...
Cocoa makes extensive use of delegates (not sure if these are similar to .net delegates) for handling unrecognised messages, which makes adding custom behaviour to classes possible without subclassing.
Rails is (in)famous for making use of Ruby's method_missing to implement all sorts of funky stuff.
Objects just aren't structs with methods on top: you can create lots of those without them ever being objects in the proper sense. Objects are a separate concept.
This view is probably prevalent because C++ more or less does (and did even more in its early days) promote objects as structs with methods and some other fanciness on top, and C++ was probably the first really widespread OO language.
That's their only difference in C++.
And so instances of structs and instances of classes are the same thing in C++ too.
You will even sometimes see member functions defined on structs.
e.g.
type Animal
type Lion < Animal
type Elephant < Animal
type Giraffe < Animal
method encounter(Animal, Animal)
def encounter(Lion a, Giraffe b):
// eat it
def encounter(Lion a, Lion b):
// fight
Is equivalent to: type Animal
type Lion < Animal
type Elephant < Animal
type Giraffe < Animal
def encounter(Animal a, Animal b):
if(a is Lion && b is Giraffe):
// eat it
else if(a is Lion && b is Lion):
// fight
else:
raise NoApplicableMethodError
Languages with predicate dispatch usually allow you to define your own predicate classes: def Prime(n): // primality testing algorithm here
def Foo(Prime n): ...
Or: type Rectangle height width
def Square(Rectangle r): height(r) == width(r)
def Something(Square x): ...
def Something(Rectangle x): ...
And they allow you to add predicates to methods themselves: def encounter(Lion a, Giraffe b) when isHungry(a): eat
def encounter(Lion a, Giraffe b) when !isHungry(a): walk away
This is much more powerful and simpler than message passing, IMO.It's closely related to pattern matching in languages like Haskell, but that's usually not allowed to span multiple modules or files. And algebraic data types are closed, making it much less useful.
Also type classes, and being able to add instances for any type are closely related to your examples.
Type classes are more powerful in some ways, but much less powerful in other ways. There is some overlap, but type classes dispatch only on the compile time type whereas this dispatches on run time predicates.
A quick search reveals that there is some support for open data types in GHC, but I am not sure if it's more than an experimental feature.