Disclaimer: I have not yet fully articulated my thoughts on the following, and I don’t have time to today. But I came across two related blog posts in a span of 10 minutes, which was sufficient synchronicity to jot down some quick thoughts.
Item 1:Moving Beyond the OOP Obsession.
This post makes use of the classic demonstration that:
…is functionally equivalent to:
…if you leave dynamic dispatch out of the picture, and indistinguishable from:
…in a parametrically polymorphic language.
Which, to be fair, is a perfectly reasonable thing to say if you learned OOP, or something called OOP, from PASCAL or C++. I say this from experience; I first encountered OOP (and became a local “OOP guru”) in C++.
The latter example is a nice segue to…
I’m not saying you should go read the linked paper. Although if you do, let me know if it’s any good. I point it out only as evidence that people are still talking about mixing OOP and parametric polymorphism (i.e. dispatching on all the arguments to a function, not just the argument to the left of the dot. Or arrow, as the case may be.)
Which, again, is a perfectly reasonable thing to be talking about if you cut your teeth on C++ and think of the thing to the left of the dot as being a syntactically-privileged leftmost argument.
I too remember the dawning realization that the thing behind the dot was “just” a surreptitious argument. What I didn’t realize at the time was that I wasn’t having an epiphany about OOP. I was having an epiphany about bunch of languages which defined OOP as “moving one of the arguments to the left of a dot, calling it
this, and maybe sometimes dynamically dispatching on it”.
To spell out the tautology more explicitly: I had discovered that in languages which put a light dusting of sugar on the first argument to a function, if you dig through the powdered sugar, you find the first argument to the function.
And the comma operator is really the K Combinator!
All of this is part of the legacy of what I have begun to think of as the “SIMULA lineage” of OOP. You can see it in PASCAL, C++, Java, C#, OO Perl, even a little bit in Python. (Historians of computing, aka programmers older than me, are welcome to argue with me about whether my attribution to SIMULA is warranted. I’m still boning up on my OO history).
I’ll bet you think I’m going to define the traits of the SIMULA lineage now. And I’d like to! But it is late, and I am tired. For the purposes of this article, I’m talking about languages which saw OOP as a) Inheritance; b) bundles of data and functions; c) method calls as being just a slightly special form of function calls.
Actually, for the sake of this discussion, only (c) matters. And the terminology “method calls” gives the whole game away.
It seems pretty clear from reading Alan Kay’s reminiscences that if he had to do it over again, he probably would have called it something like “message oriented programming” rather than “object oriented programming”. “Method calls” do not enter into it.
Let’s just cut to the chase, since I am tired[ibid]. Contrary to the fevered imaginings of my language-feature-happy younger self, OOP and parametric polymorphism together are an oxymoron. If “the system” has to convene a committee meeting—either at compile time or runtime—of all the arguments to determine how to dispatch a message, it’s not message passing and it’s not OOP.It’s just obfuscated procedural code, or uglified functional code. It has lost all the constraints on the possibility space that make OOP compelling.
In which case you’d be perfectly justified in wondering what the leftmost argument is doing putting on airs, jumping the parentheses, and putting a dot between itself and the proles.
Note: I wrote this pretty tired, and as several commenters pointed out I mixed up some of my terminology. I’m closing comments because apparently this is on HN now and I don’t feel like dealing with a zillion comments pointing this fact out to me on a Friday night. Yes, parametric polymorphism was the wrong term. What I was getting at was probably more like the overlap of ad-hoc polymorphism (in static languages) and multiple dispatch (in dynamic languages). But I don’t have time to confirm this right now.