Nygaard and Ole-Johan Dahl built Simula at the Norwegian Computing Center to simulate things like ships moving through harbors and customers waiting in queues. Simula I (1962-65) was a simulation language. Simula 67 generalized it and gave us nearly the whole kit: classes, objects, subclasses, virtual procedures (dynamic dispatch), and coroutines, so each object could run its own little process. They shared the Turing Award for it in 2001. Nygaard went on to design BETA with Ole Lehrmann Madsen and Birger Møller-Pedersen, and to pioneer participatory design, working with trade unions on how workers should have a say in the systems imposed on them. He never thought of programming as separate from the people it was for.
https://cs.au.dk/nygaard100years/celebration
https://news.ycombinator.com/item?id=49850612
>Speaking of vtables, at Kristen Nygaard's 100-year birthday celebration Bjarne Stroustrup also gave a fascinating talk after Alan Kay's, and they had some spicy back-and-forth discussion afterwards! Both call themselves Nygaard's heirs, and it was a delightful and respectful interplay between very different world views.
>Kay came to Simula as a reader, turned it into Smalltalk, and later knew Nygaard and Dahl as colleagues. Stroustrup was taught by Nygaard in person, as a student at Aarhus, and then used Simula for his PhD.
>Roughly: Stroustrup said he never took much from Smalltalk. What he took from Simula was the static part, compile-time guarantees and a direct map to hardware with zero-overhead abstraction, and C++ was never meant to be just an object-oriented language, since not everything is a class hierarchy or a virtual function. Kay argued that late binding pays for itself because the human is the slow part of an interactive system, and that static typing is a good idea applied prematurely. They agreed that the real job of an operating system or the internet is never to crash and never lose anything, and came at it from opposite ends: Stroustrup is working on guarantees against dangling pointers, out of range access, and uninitialized memory in C++, while Kay pointed out that Smalltalk protected every object dynamically.
Simula inspired two very different children.
Alan Kay saw Simula I and Sketchpad in the same week in grad school at Utah in 1966, and it gave him the idea that everything could be like a little computer: protected, self-contained processes that only communicate by sending messages. When someone asked what he was working on, he flippantly answered "object-oriented programming", and the name stuck. Smalltalk kept Simula's classes, but the big idea was messaging. As he put it in 2003: "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things."
Bjarne Stroustrup used Simula for his PhD simulations at Cambridge, loved how it let him structure programs, and found the implementation far too slow. So in 1979 he bolted Simula's classes onto C, and "C with Classes" became C++. It kept the classes and the static types, and dropped the messaging and most of the late binding, so the compiler could make it fast.
Alan has been drawing the contrast ever since. In his own words, correcting someone here who misquoted him: "I invented the term 'object-oriented', and I didn't have C++ in mind."
Then David Ungar and Randy Smith took something away. Self removed the classes. Only objects remain, and they inherit directly from other objects through parent slots. An object can have several parents, so you get multiple inheritance for free, and since parents are just slots, you can change them at runtime. There's no assignment syntax either: variables are slots you send messages to. The title of the 1987 paper says what it was about: "Self: The Power of Simplicity."
A language that dynamic was supposed to be too slow to use, so Craig Chambers, Urs Hölzle and Ungar invented the techniques that made it fast anyway: maps (hidden classes), customization, polymorphic inline caches, adaptive recompilation, and deoptimization (pessimization) so you could still debug optimized code.
That work went through Animorphic's Strongtalk to Sun and became Java's HotSpot, and Lars Bak carried it on into V8 for JavaScript. JavaScript's design credited Self, but missed the point by subtracting the one thing Self was about: simplicity. Brendan Eich never understood simplicity, or even the $1000 question: equality.
https://dorey.github.io/JavaScript-Equality-Table/
Anders Hejlsberg, who designed Turbo Pascal, Delphi, C#, and then TypeScript to clean up after JavaScript, at a 2019 panel with Guido van Rossum, James Gosling and Larry Wall:
https://news.ycombinator.com/item?id=19568378
>"My favorite is always the billion dollar mistake [Tony Hoare's name for null] of having null in the language. And since JavaScript has both null and undefined, it's the two billion dollar mistake." -Anders Hejlsberg
>"It is by far the most problematic part of language design. And it's a single value that -- ha ha ha ha -- that if only that wasn't there, imagine all the problems we wouldn't have, right? If type systems were designed that way. And some type systems are, and some type systems are getting there, but boy, trying to retrofit that on top of a type system that has null in the first place is quite an undertaking." -Anders Hejlsberg
Self's ideas (speculate on what you've observed, guard the assumption, bail out when it breaks) are how everybody's JIT works now, from .NET's tiered compilation for C# to LuaJIT's traces. Separately, Self's prototypes became JavaScript's object model, and Lua's metatables follow the same prototype approach.
The irony is that Self's compiler was the reward for simplicity, and it became the subsidy and license for complexity. The same techniques now make Java, JavaScript, C# and Lua run fast no matter how complicated their object models get, which flies in the face of the key word Ungar and Smith put in the title: simplicity.
Then Ungar, Harold Ossher and Doug Kimelman at IBM took the next thing away. Korz removed the objects and kept the slots. A program is a flat sea of slots that belong to nothing, each guarded on named dimensions, and a message is sent in a context of dimension bindings that flows implicitly down the call chain. The receiver becomes one ordinary dimension (rcvr) among any number. Group the slots by rcvr and you see ordinary objects again, but that's just one view, and no view is the privileged one. Once again the title leads with the point: "Korz: Simple, Symmetric, Subjective, Context-Oriented Programming" (Onward! 2014).
https://dl.acm.org/doi/10.1145/2661136.2661147
The name comes from Alfred Korzybski, whose Science and Sanity (1933) argued how much perspective shapes perception, and who gave us "the map is not the territory." It's a fitting name, because Self's implementation was built on maps: hidden structures describing the layout of objects that share a shape, which the programmer never sees, while the objects themselves are the territory. (V8 still calls its hidden classes Maps.) In Korz it's the other way around. The slots are the territory, and objects are just maps of it, one of many possible projections. Self hid its maps behind the objects, and Korz shows the objects were maps all along.
Look at that title and you can see what happened in between. When the receiver is the only thing allowed to vary behavior, everything else that needs to vary behavior has to start its own movement. Subject-oriented programming (Harrison and Ossher, 1993) varies by who is looking. Aspect-oriented programming (Kiczales et al. at PARC, 1997) varies by which concern cuts across. Context-oriented programming (Hirschfeld, Costanza and Nierstrasz, around 2005-2008) varies by what situation you're in. Then there's feature-oriented, role-oriented, and the rest.
Each one takes the same mechanism and freezes a different dimension into its name. Ossher co-invented subject-oriented programming, and with Korz he and his colleagues argued that all of these are projections of one smaller mechanism: dispatch on any number of named dimensions.
So I propose continuing the tradition by removing the next thing that complicates matters: the modifier. Object-Oriented Programming, minus the Object guard, is just Oriented Programming. Behavior is chosen by where you stand along whatever dimensions you've declared, and none of them is privileged in the name. How it's oriented matters less than whether it's oriented.
Oriented languages have one declared bearing that everything else follows, whatever that bearing is: Smalltalk and Self (objects receiving messages), CLOS (generic functions dispatching on all their arguments, with method combination), Korz (slots, guards and dimensions), Erlang (isolated processes sending messages, which is why Joe Armstrong concluded it might be the only object-oriented language), Lisp (lists), Forth (the stack), APL (arrays), Tcl (strings), Lua (tables), Prolog, Datalog and SQL (relations), and Unix (files and pipes).
The corollary is Disoriented Programming: a language that names one dimension in its paradigm, while its real behavior depends on a dozen unstated ones scattered across unrelated mechanisms. It comes in two flavors, naive and diabolical.
The classic naive case is PHP. It was never designed so much as accreted, one "next logical step" at a time, with open contempt for computer science and for design itself. Rasmus Lerdorf said as much: "I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way." and "We have things like protected properties. We have abstract methods. We have all this stuff that your computer science teacher told you you should be using. I don't care about this crap at all." The result has no bearing at all: functions, classes, traits, magic methods, superglobals, variable variables, and a standard library whose argument order you have to look up every time.
https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
C++ is disoriented in many of the same ways, but on purpose. Every mechanism was deliberately chosen, carefully argued, and added on the principle that you don't pay for what you don't use. The upshot is that the behavior of a single call can depend on classes, templates, overloading, argument-dependent lookup, virtual versus non-virtual, implicit conversions, macros and friends, all interacting exactly as specified. That's diabolical, and Stroustrup knew it: "Within C++, there is a much smaller and cleaner language struggling to get out." It's still not what Alan had in mind.
Most other mainstream languages drift somewhere between those two poles. In enterprise Java, annotations, reflection, dependency injection and aspect weavers decide more than the classes do. JavaScript has prototypes underneath, class syntax on top, and several different rules for what "this" means. C# and Scala keep adding features instead of taking them away.
Disoriented doesn't mean useless. Those dimensions of variation are real and necessary, which is exactly why all those mechanisms got bolted on. It's disoriented to pretend there's only one direction on the compass, and hide all the others in places the language won't admit are part of the model.
I've written this up at more length as a Chip Morningstar-style "How to Deconstruct Almost Anything" deconstruction: declassification, then deobjectification, then what's left:
How to Deconstruct Almost Anything:
https://www.fudco.com/chip/deconstr.html
https://news.ycombinator.com/item?id=6389498
How to Disorient Almost Anything:
https://github.com/SimHacker/moollm/blob/main/designs/korz/d...
>Marvin Minsky saw the same enthronement in psychology. In a 1982 essay he demolished what he called the Single Agent theory -- the folk idea of "a little person deep down there" who does the real mental work -- and concluded: "Self, itself, is not a single thing." He wrote that five years before Self the language shipped, and it reads as a prophecy of what came next.
That leaves an open question for David Ungar: having demoted the receiver, would he go the rest of the way, drop the modifier, and call the whole genre Oriented Programming?