被遗忘的面向对象历史 未翻译

oschina 投递于 01/08 15:05 (共 22 段)
阅读 37
收藏 0
0
加载中

Note: This is part of the “Composing Software” series (now a book!) on learning functional programming and compositional software techniques in JavaScript ES6+ from the ground up. Stay tuned. There’s a lot more of this to come!
< Previous | << Start over at Part 1

The functional and imperative programming paradigms we use today were first explored mathematically in the 1930s with lambda calculus and the Turing machine, which are alternative formulations of universal computation (formalized systems which can perform general computation). The Church Turing Thesis showed that lambda calculus and Turing machines are functionally equivalent — that anything that can be computed using a Turing machine can be computed using lambda calculus, and vice versa.

已有 1 人翻译此段(待审批)
我来翻译

Note: There is a common misconception that Turing machines can compute anything computable. There are classes of problems (e.g., the halting problem) that can be computable for some cases, but are not generally computable for all cases using Turing machines. When I use the word “computable” in this text, I mean “computable by a Turing machine”.

Lambda calculus represents a top-down, function application approach to computation, while the ticker tape/register machine formulation of the Turing machine represents a bottom-up, imperative (step-by-step) approach to computation.

Low level languages like machine code and assembly appeared in the 1940s, and by the end of the 1950s, the first popular high-level languages appeared. Lisp dialects are still in common use today, including Clojure, Scheme, AutoLISP, etc. FORTRAN and COBOL both appeared in the 1950s and are examples of imperative high-level languages still in use today, though C-family languages have replaced both COBOL and FORTRAN for most applications.

还没有人翻译此段落
我来翻译

Both imperative programming and functional programming have their roots in the mathematics of computation theory, predating digital computers. “Object-Oriented Programming” (OOP) was coined by Alan Kay circa 1966 or 1967 while he was at grad school.

Ivan Sutherland’s seminal Sketchpad application was an early inspiration for OOP. It was created between 1961 and 1962 and published in his Sketchpad Thesis in 1963. The objects were data structures representing graphical images displayed on an oscilloscope screen, and featured inheritance via dynamic delegates, which Ivan Sutherland called “masters” in his thesis. Any object could become a “master”, and additional instances of the objects were called “occurrences”. Sketchpad’s masters share a lot in common with JavaScript’s prototypal inheritance.

还没有人翻译此段落
我来翻译

Note: The TX-2 at MIT Lincoln Laboratory was one of the early uses of a graphical computer monitor employing direct screen interaction using a light pen. The EDSAC, which was operational between 1948–1958 could display graphics on a screen. The Whirlwind at MIT had a working oscilloscope display in 1949. The project’s motivation was to create a general flight simulator capable of simulating instrument feedback for multiple aircraft. That led to the development of the SAGE computing system. The TX-2 was a test computer for SAGE.

The first programming language widely recognized as “object oriented” was Simula, specified in 1965. Like Sketchpad, Simula featured objects, and eventually introduced classes, class inheritance, subclasses, and virtual methods.

Note: A virtual method is a method defined on a class which is designed to be overridden by subclasses. Virtual methods allow a program to call methods that may not exist at the moment the code is compiled by employing dynamic dispatch to determine what concrete method to invoke at runtime. JavaScript features dynamic types and uses the delegation chain to determine which methods to invoke, so does not need to expose the concept of virtual methods to programmers. Put another way, all methods in JavaScript use runtime method dispatch, so methods in JavaScript don’t need to be declared “virtual” to support the feature.

还没有人翻译此段落
我来翻译

The Big Idea

“I made up the term ‘object-oriented’, and I can tell you I didn’t have C++ in mind.” ~ Alan Kay, OOPSLA ‘97

Alan Kay coined the term “object oriented programming” at grad school in 1966 or 1967. The big idea was to use encapsulated mini-computers in software which communicated via message passing rather than direct data sharing — to stop breaking down programs into separate “data structures” and “procedures”.

“The basic principal of recursive design is to make the parts have the same power as the whole.” ~ Bob Barton, the main designer of the B5000, a mainframe optimized to run Algol-60.

Smalltalk was developed by Alan Kay, Dan Ingalls, Adele Goldberg, and others at Xerox PARC. Smalltalk was more object-oriented than Simula — everything in Smalltalk is an object, including classes, integers, and blocks (closures). The original Smalltalk-72 did not feature subclassing. That was introduced in Smalltalk-76 by Dan Ingalls.

还没有人翻译此段落
我来翻译

While Smalltalk supported classes and eventually subclassing, Smalltalk was not about classes or subclassing things. It was a functional language inspired by Lisp as well as Simula. Alan Kay considers the industry’s focus on subclassing to be a distraction from the true benefits of object oriented programming.

“I’m sorry that I long ago coined the term “objects” for this topic because it gets many people to focus on the lesser idea. The big idea is messaging.”
~ Alan Kay

In a 2003 email exchange, Alan Kay clarified what he meant when he called Smalltalk “object-oriented”:

“OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.”
~ Alan Kay

In other words, according to Alan Kay, the essential ingredients of OOP are:

  • Message passing

  • Encapsulation

  • Dynamic binding

Notably, inheritance and subclass polymorphism were NOT considered essential ingredients of OOP by Alan Kay, the man who coined the term and brought OOP to the masses.

还没有人翻译此段落
我来翻译

The Essence of OOP

The combination of message passing and encapsulation serve some important purposes:

  • Avoiding shared mutable state by encapsulating state and isolating other objects from local state changes. The only way to affect another object’s state is to ask (not command) that object to change it by sending a message. State changes are controlled at a local, cellular level rather than exposed to shared access.

  • Decoupling objects from each other — the message sender is only loosely coupled to the message receiver, through the messaging API.

  • Adaptability and resilience to changes at runtime via late binding. Runtime adaptability provides many great benefits that Alan Kay considered essential to OOP.

These ideas were inspired by biological cells and/or individual computers on a network via Alan Kay’s background in biology and influence from the design of Arpanet (an early version of the internet). Even that early on, Alan Kay imagined software running on a giant, distributed computer (the internet), where individual computers acted like biological cells, operating independently on their own isolated state, and communicating via message passing.

还没有人翻译此段落
我来翻译

“I realized that the cell/whole-computer metaphor would get rid of data[…]”
~ Alan Kay

By “get rid of data”, Alan Kay was surely aware of shared mutable state problems and tight coupling caused by shared data — common themes today.

But in the late 1960s, ARPA programmers were frustrated by the need to choose a data model representation for their programs in advance of building software. Procedures that were too tightly coupled to particular data structures were not resilient to change. They wanted a more homogenous treatment of data.

“[…] the whole point of OOP is not to have to worry about what is inside an object. Objects made on different machines and with different languages should be able to talk to each other […]” ~ Alan Kay

还没有人翻译此段落
我来翻译

Objects can abstract away and hide data structure implementations. The internal implementation of an object could change without breaking other parts of the software system. In fact, with extreme late binding, an entirely different computer system could take over the responsibilities of an object, and the software could keep working. Objects, meanwhile, could expose a standard interface that works with whatever data structure the object happened to use internally. The same interface could work with a linked list, a tree, a stream, and so on.

Alan Kay also saw objects as algebraic structures, which make certain mathematically provable guarantees about their behaviors:

“My math background made me realize that each object could have several algebras associated with it, and there could be families of these, and that these would be very very useful.”
~ Alan Kay

还没有人翻译此段落
我来翻译

This has proven to be true, and forms the basis for objects such as promises and lenses, both inspired by category theory.

The algebraic nature of Alan Kay’s vision for objects would allow objects to afford formal verifications, deterministic behavior, and improved testability, because algebras are essentially operations which obey a few rules in the form of equations.

In programmer lingo, algebras are like abstractions made up of functions (operations) accompanied by specific laws enforced by unit tests those functions must pass (axioms/equations).

Those ideas were forgotten for decades in most C-family OO languages, including C++, Java, C#, etc., but they’re beginning to find their way back into recent versions of most widely used OO languages.

还没有人翻译此段落
我来翻译
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(0)

返回顶部
顶部