TITLE: A Blog Entry From Before I Had a Blog
AUTHOR: Eugene Wallingford
DATE: March 07, 2006 6:44 PM
Back when I
started this blog,
I commented that "the hard drive of every computer
I've ever had is littered with little snippets and
observations that I would have liked to make available
to someone, anyone, at the time." At the time, I
thought that I might draw on some of my old writings
for my blog. That hasn't happened, because I've
usually either had something new to write about that
interested or had no time to blog at all.
Apparently, not all of my old writings ended up in
dead files somewhere. While I was getting ready for
my compiler class today, I looked over the lecture
notes from the corresponding session the last time
I taught this course. The date was November 4, 2003,
and I had just returned from OOPSLA in Anaheim. I
was excited about the conference, I'm sure, as I
always am, and used part of my first class back to
share some of what I had learned at the conference.
(I wouldn't be surprised if part of my motivation
in sharing was avoid diving head-first back into
semantic analysis right away... :-)
My lecture notes for that day looked a lot like a
set of blog entries! So it seems that my students
were unwitting, though not unwilling, audience for
my blogging before this blog began.
I enjoyed re-reading one of these OOPSLA'03 reports
enough that I thought I'd polish it up for a wider
audience. Here is an excerpt from my compiler
lecture notes of 11/04/03, on David Ungar's keynote
address, titled "Seven Paradoxes of Object-Oriented
Programming Languages". I hope you enjoy it, too.
OOPSLA 1: David Ungar's Keynote Address
David Ungar of Sun Microsystems gave an
at OOPSLA last week, entitled "Seven Paradoxes of Object-Oriented
His abstract lists seven paradoxes about language that he thinks make
designing a good programming language so difficult. He titled and
focused his talk on object-oriented languages, given his particular
audience, but everything he said applies to languages more generally,
and indeed to most design for human use. His points are about language
design, not compiler design, but language design has a profound effect
on the implementation of a compiler. We've seen this at a relatively
low level when considering LL and LR grammars, and it applies at higher
He only addressed three of his paradoxes in the talk, and then in a more
1. Making a language better for computers makes it worse for people,
and vice versa.
He opened with a story about his interview at MIT when he was looking
for his first academic position. One interviewer asked him to define
'virtual machine'. He answered, "a way to give programmers good error
messages, so that when there weren't any error messages the program
would run successfully". The interviewer said, "If you believe that,
then we have nothing more to talk about it." And they didn't. (He
got the offer, but turned it down.)
A programming language has to be mechanistic and humanistic, but in
practice we let the mechanistic dominate. Consider: write a Java class
that defines a simple stack of integers. You'll have to say int
five times -- but only if you want 32-bit integers; if you want more or
less, you need to say something else.
The machines have won! How can we begin to design languages for people?
We first must understand how they think. Some ideas that he shared from
If class-based languages pose such problems, what is the alternative?
How about an instance-based language? One example is
a language designed by Ungar and his colleagues at Sun. But instance-based
languages pose their own problems...
2. The more concepts we add to a language, the less general code that
He opened with a story about his first big programming assignment in
college, to write an assembler. He knew APL best -- a simple language
with few concepts but powerful operators. He wrote a solution in
approximately 20 lines of code. How? By reading in the source as a
string and then interpreting it.
Some of his PL/1-using classmates didn't get done. Some did, but they
wrote hundreds and hundreds of lines of code. Why? They could have
done the same thing he did in APL -- but they didn't think of it!
But why? Because in languages like Fortran, PL/1, C, Java, etc., programs
and data are different sorts of things. In languages like APL, Lisp,
Smalltalk, etc., there is no such distinction.
Adding more concepts to a language -- such as distinguishing programs from
data -- impoverish discourse because they blind us, create a mindset that
is focused on concepts, not problems.
Most OOPs adopt a classes-and-bits view of objects, which encourages
peeking at implementation (getters/setters, public/private, ...).
Could create a better language that doesn't distinguish between data
and behavior? Self also experiments with this idea, as do Smalltalk
Adding a feature to a language solves a specific problem but degrades
learnability, readability, debuggability -- choosing what to say.
(Why then do simpler languages like Scheme not catch on? Maybe it's
not a technical issue but a social one.)
What is an alternative? Build languages with layering -- e.g., Smalltalk
control structures are built on top of blocks and messages.
3. Improving the type system of a language makes the type system
This part of Ungar's talk was more controversial, but it's a natural
application of his other ideas. His claim: less static type checking
implies more frequent program change, implies more refactoring, implies
So what? We can use these ideas to understand our languages and the ways
we program in them. Consider Java and some of the advice in Joshua Bloch's
- Abstractions are in your head, not in the world. A class of objects
is an abstraction. An abstract data type is an abstraction. An
integer is an abstraction. The idea of identity is an
Our programming languages must reflect a consciousness of
abstraction for even the simplest ideas; in C++ and Java, these
include const, final, and ==. (A
final field in Java cannot be modified, but its value
can change if it is a mutable object...)
- From the moment of perception, our bodies begin to guess at
abstractions. But these abstractions are much 'softer' than their
equivalents in a program.
- Classical categories -- classes of objects -- are defined in terms
of shared features. This implies a symmetry to similarity and
representativeness. But that is not how the human mind seems to
work. Example: birds, robins, and ostriches. For humans, classes
are not defined objectively in our minds but subjectively, with fuzzy
notions of membership.
One interesting empirical observation: People treat the middle
of a classification hierarchy as the most basic unit, not the root
or leaves. Examples: cat, tree, linked list.
- Why is state so important to us in our programs? Because the
'container' metaphor seems deeply ingrained in how we think about
the world. "The variable x 'holds' a 4", like a box. The same
metaphor affects how we think about block structure and single
inheritance. But the metaphor isn't true in the world; it's just
a conceptual framework that we construct to help us understand.
And it can affect how we think about programs negatively
(especially for beginners!?)
Ambiguity communicates powerfully. We just have to find a way to make
our machines handle ambiguity effectively.
[end of excerpt]
As with any of my conference reports, the ideas presented belong
to the presenter unless stated otherwise, but any mistakes are
The rest of this lecture was a lot like my other conference-themed
blog entries. Last week, I blogged about the
at SIGCSE; back in late 2003 I commented on the buzz surrounding
the relatively new IDE named
And, like many of my conference visits, I came back with a long
list of books to read, including "Women, Fire, and Dangerous
Things", by George Lakoff, "The Innovator's Dilemma", by Clayton
Christensen, and "S, M, L, XL", by Rem Koolhaas and Bruce Mau.
Some things never change...
- "Use a factory method, not a constructor."
What went wrong? Lack of consciousness of abstraction. Richer
is poorer (constructor distinctive from message send).
- "Override hashCode() when you override equals()."
What went wrong? Better types are worse. Why doesn't the type
system check this?