1. 32
  1.  

  2. 11

    This is probably the farthest I’m willing to push “newsletter isn’t lobsters appropriate”, since it has a couple of adverts and other links. But other people have been submitting my newsletter posts and they’ve been going over extremely well here, and I think “why message passing is interesting” something that would particularly appeal to the lobsters crowd.

    (Also, it’s a 1,300 word essay, so IMO passes the bar for “informative content” and not just clickbait)

    1. 3

      This might seem like only sophistry… until you consider open-world systems.

      Oh. So if we really try to decipher and oversimplify all of that, “proper” OOP being “like Smalltalk/Ruby not C++” really is about the dynamic/interpreted nature of the language.

      1. 8

        Sort of, but dynamic does not imply interpreted. Objective-C is fully dynamic in this sense, but also compiles to machine code just like C. (While Java is interpreted but not dynamic.)

        1. 2

          Java is not necessarily interpreted (see for example gcj or the llvm java front end); and does have dynamic message-passing: while signatures are looked up at compile time, method implementations are resolved at runtime (see, for example, java.lang.reflect.Proxy).

      2. 3

        Until reading this, I hadn’t grasped why LISP was considered a good message-passing system by Alan Kay. Obviously you can do anything in LISP, but as the article mentioned, Python does that too.

        Now I understand it’s referring specifically to the fact that this is perfectly normal Clojure: ((foo obj) list element x). Although in this case, the message isn’t being dispatched to the list, it’s the function. In Clojure this is less clear due it’s protocol support, so maybe it would invoke a method controlled by the list type, and maybe it wouldn’t.

        1. 1

          This is not quite right. Kay wants dynamic late binding. That means:

          (+ 42 69)
          

          being a message isn’t interesting unless:

          (define (+ x y) ...)
          

          (or similar) is also a message that could be sent independently as part of some other event.

        2. 2

          Hey @hwayne, have you ever looked at Oberon? It’s arguably the most minimalistic Wirth language, but it still has this notion of extending a record (say, Message) and then later matching on extensions you can handle and ignore the other ones. This recent post is what got me interested.

          The key to this flexibility was a departure from the traditional object-oriented

          model of class-based dynamic dispatch with implementation inheritance . Oberon replaced this model with an architecture in which the messages themselves were represented by objects.

          1. 2

            EDIT: Forgot which post I was responding to, I clicked on this link, responded to it as if it was the OP. Oops!

            I’ll leave this up for prosperity

            I feel like this is misunderstanding what Alan Kay (perhaps) intended (Ultimately, neither of us can know his true intentions). Language is a shorthand and this takes a too-literal meaning of what he said, not to mention that these quotes are out of context. When I read the quote:

            OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.

            I take it in the context that he has, roughly, 50-odd years of experience since they started writing Smalltalk (Work started on it in 1969!), and so I read it as that he is saying:

            OOP to me, now means only messaging, local retention and protection and hiding of state-processes, and extreme late-binding of all things. These things are handled well in Smalltalk and LISP, but I am not aware of any other systems that do these things as a matter of course

            Or rather that he’s saying

            The most interesting things to take away from my work with OOP, right now are […]

            In addition this

            The idea that classes and objects were secondary to the messages comes much later.

            seems to not understand the amount of time and experience that allows one to look back. It doesn’t matter, to a certain degree, what they thought at the time, what matters is hindsight, and it is possible to change your opinion about things after they have happened. It’s entirely possible and pretty likely that, after building a system, the things you valued about the system while you were building it won’t seem as important as other concepts that you built into the system.

            Not to mention that, everything you say puts message passing as the primary influence here. You yourself say that the main things to credit Smalltalk with, are:

            • There were no non-object primitives. Numbers were objects. Errors were objects. Classes were objects. Messages were objects.
            • You could pass a message to any object, including other messages.
            • Methods and implementations were associated with the objects, not the session.

            Well, look at the later systems, the most famous one being Java. Are those things true of Java and the descendent systems? From my experience, no. From what I can tell, aside from Erlang, the things that made Smalltalk so powerful have been largely ignored by Computer Science as a field.

            The point of what Kay is saying then, is not so much that Object-Oriented Systems do not exist, as you seem to be claiming him to say, but instead that people in Computer Science missed what made Smalltalk special – and the main thing that they could stand to benefit from, is a robust and universal message passing system, along with the universality of objects. And that is, after a long time working with these systems, what he sees as the valuable aspect now.

            1. 1

              Are those things true of Java and the descendent systems? From my experience, no.

              Java, like C++, C# and most other strongly-typed languages, is not dynamic enough for “full” Alan-Kay-style OOP. But dynamic OO languages like Python, Ruby and JS, fit his criteria pretty well.

              From what I can tell, aside from Erlang, the things that made Smalltalk so powerful have been largely ignored by Computer Science as a field.

              I disagree. (And I would not call Erlang an OO language at all. It does have message passing between special entities called processes, but it has no objects.)

              1. 3

                I disagree. (And I would not call Erlang an OO language at all. It does have message passing between special entities called processes, but it has no objects.)

                What is an object then? You can instantiate processes and send them messages. They encapsulate state and hide implementation details. The language creator goes into detail on this topic here: https://www.infoq.com/interviews/johnson-armstrong-oop/

                I feel like this is misunderstanding what Alan Kay (perhaps) intended

                @alexandria We don’t need to guess what Alan Kay thinks. He was asked on Quora what he thinks about Joe Armstrong (Erlang creator) claiming that Erlang might be the only truly object oriented language:

                I love Joe Armstrong — we lost a great man when he recently left us.

                And, he might be right. Erlang is much closer to the original ideas I had about “objects” and how to use them.

                However, another way to look at this is to consider “What Is Actually Needed” (WIAN) and realize that much more is needed beyond what we are programming in today.

                source: https://www.quora.com/What-does-Alan-Kay-think-about-Joe-Armstrong-claiming-that-Erlang-might-be-the-only-object-oriented-language-and-also-his-thesis-supervisor-s-claim-that-Erlang-is-extremely-object-oriented

            2. 2

              Unrelated aside, but Judea Pearl invented an algorithm in 1982 for approximate inference on probabilistic graphical models which is (somewhat confusingly) also called message passing.

              1. 1

                This is a great topic, but I disagree about details. It feels like @hwayne is focusing too much on syntax. For example:

                There is one key difference, though, between obj.f(x) and f(obj, x): where the source code is. In the former case, you could carry the code in the object itself as opposed to the global namespace.

                Actually you can do it in either case. Nim treats those two call types as identical. Either way, the call can be statically or dynamically bound depending on how the functions are declared. (It’s still not a true message-send, rather vtable-based, but that’s not relevant to this point.)

                list (obj foo) element: x

                I don’t remember that as valid Smalltalk-80 syntax, but it’s been a long time. IIRC you would say list perform: obj foo with: x, where obj foo returns a selector, i.e. an interned method/function name.

                The same thing works in Objective-C too; not surprising since its object model was directly, uh, modeled on Smalltalk.

                I don’t understand why your Python example is considered convoluted or going against the grain. Python (and Ruby and JS and their ilk) are all, like ST80, message-passing languages where objects have dictionaries mapping selectors to implementations, and computing the selector at runtime is a very valid feature of that model.

                1. 2

                  Actually you can do it in either case. Nim treats those two call types as identical. Either way, the call can be statically or dynamically bound depending on how the functions are declared. (It’s still not a true message-send, rather vtable-based, but that’s not relevant to this point.)

                  I think Nim has the advantage of being several decades later, when the state-of-art has progressed considerably. I don’t know how much this replaces message passing, though.

                  I don’t understand why your Python example is considered convoluted or going against the grain

                  It just feels a bit clunkier to me, I think? Like you can’t just dynamically pick the message, you have to first cast to a string, which is less rich of a semantics. I’ll see if I can come up with an example of where this because messier.

                  1. 3

                    What, exactly, is a message? I had an epiphany years ago that your typical function call (like you do in C) is nothing more than a synchronous by value message (I wrote about this two years ago). All it comes down to is how you interpret the bits you receive. One can certainly write a program with functions defined like msg__t foo(msg__t) where msg__t is a structure (or even array—there isn’t that much of a difference between the two) and it’s up to the function to interpret the meaning as it sees fit. Yeah, it gets annoying to call a function when you have to first fill in a structure, but that’s comparable to calling a C function in assembly, where you have to push all the parameters on the stack.

                    1. 1

                      I know what you mean, but “clunkier” is just a matter of syntax, and syntax isn’t the important thing about messaging. (Unless the facility isn’t there at all and has to be implemented as a clunky user-level library, which I agree makes a big difference.)

                      Anyway, I want to add a point about messaging not being a panacea. Yes, you can combine independent programs and make them communicate, but you are likely to run into higher level problems of semantics. Just because two programs use a common message name, it doesn’t follow that they attach the same meaning to it. I’ve run into this with ambiguous English words like “read” — does the read method read data from somewhere, or is it a predicate telling whether the object has been read?

                      So in practical use, you need to define a fairly precise schema of messages. Which, ironically, is what you end up doing in a statically-typed language with interfaces/protocols.

                      1. 4

                        Anyway, I want to add a point about messaging not being a panacea. Yes, you can combine independent programs and make them communicate, but you are likely to run into higher level problems of semantics.

                        Oh yeah, totally agreed. I just wrote this because I’ve seen people say that message passing is important without explaining why it’s different from everything else we have, so I was trying to formalize that. I don’t believe that message passing is revolutionary for making open-systems, and it has issues of its own.