Evolving the Java Language
We're starting to think about potential language features
for Dolphin (7.0). So I've been reflecting a little on the
principles that James so brilliantly infused into the original
Java language and which we've tried to preserve as it evolves.
The big core principle is around making programs easy to understand.
Java is focused on being a powerful but simple language, easy to read,
with a consistent clear meaning. It is more important that Java programs be easy to read than to write.
That may sound trivial, but it isn't.
Lessons from C++
Looking back at C++ there were a whole set of factors at work that
made reading source code difficult:
- First, the C++ language itself became very
complex. Many new ideas were added incrementally and unfortunately the seams show.
- Second, the C++ language consciously chose to emphasize "power"
That sounds nice initially, but unfortunately it also means
that there is very little you can rely on and almost
any simple program statement can have weird side effects.
In C++ the statement "a = b;" must be approached
- Finally, the macro pre-processor reinforced
the "power" aspect, but again at risks to comprehension.
Many project teams working with C++ adopted conventions
to create simpler subsets of C++. "We'll use this, but won't
use that." This helped. However, it lead to the problem
of language fragmentation, where different teams adopted
different language subsets and then got cognitive dissonance
when they read one another's source.
The Java approach
The Java language took a very different approach. Java tries
to be an unobtrusive language. As a developer, you should
be able to focus on what your application code is doing and on
how it interacts with libraries.
Code should do what it seems to do - people shouldn't need
to worry about clever language side effects or about what "=" means this week.
This focus on clarity and on readability has affected
Java in many ways. It has led to a focus on keeping the
language simple and clear. It has led to relatively
conservative uses of syntax and minimized the places where
user defined code can modify base semantics.
As another part of this principle, there is also a strong focus on having
"one standard language" which means the same thing everywhere.
It should be possible for a Java
developer to start reading a chunk of new Java source code and to
be able to rely on a consistent set of language semantics.
I shouldn't have to worry about different vendors
implementing language features in different ways.
And I really shouldn't have to read your compiler flags in order
to understand what your source code will do.
So part of our investment in the Java language includes a
strong focus on both a very precise specification (currently
driven by Sun's esteemed
and also an extensive language compatibility test suite.
Language updates in Tiger
Now principles are good, but so are pragmatics. If we
stuck too rigorously to our principles, we'd probably
never dare make any changes to the language. It is
natural for things to evolve, and we want to be able
to make developers more productive, within the spirit
of the language. But we are also very
conscious that adding individually useful features
may slowly undermine the deep values of the language.
A lot of thought went into the Tiger language features.
We reviewed scores of potential language
changes before settling on the small set that made
it into Tiger.
There is always a risk in any change, but I think the
Tiger features will help developers without disrupting
their ability to understand Java code.
- Generics are clearly a major change which add important
new type systems ideas. But they provide a deep benefit
in improved source readability (you can see what specific
types are being used, you don't have to guess) and in improved
type checking, which is a core Java virtue.
- I'm a big fan of both the extended for loop semantics and
the auto-boxing and unboxing features. At first glance
they run the risk of heading into the C++ quagmire of
user defined side effects. But in reality, they are both
tightly bounded and run little risk of surprising developers.
And they do remove some common drudgery.
- JSR-175 (Metadata Annotations) is one of the biggest
opportunities and one of the biggest risks in Tiger. It adds
a great deal of expressive power. It defines explicit
language support for a style of declarative programming
which was previously addressed through scattered ad-hoc mechanisms
(such as JavaBeans method naming conventions or marker interfaces
or EJB deployment descriptors).
By promoting this declarative programming style into the
language we hope to improve overall readability. We've also
tried to define clear rules for what annotations can and
can not do, to minimize the risks of weird side effects.
For Dolphin, as for Tiger, a lot of people both inside
and outside of Sun will be involved in reviewing any language change
proposals. The detailed designs will be handled through the JCP.
But my suspicion is that
we'll probably continue to stay very
conservative on changes, as each little change also
carries its little wad of additional complexity.
We're unlikely to add
a macro preprocessor (sorry) or any general form of operator
overloading, or full-blown AOP, or any other mechanism for redefining and obscuring core semantics.
But we will look for new language ideas that help developers
with common problems. For example, one area I'm personally interested
in is some kind of "friends" import mechanism to make large
multi-package projects easier to manage.
One platform, many languages
One last thought: the Java language is only one language
for the Java Platform. It has one particular set of values,
which seem to be particularly good for creating large,
But different developers want different things at different
times. It's OK to have multiple languages, each of which
is well designed for a specific kind of programming.
When I'm doing a quick Sunday morning hack, sometimes
I want something more scripty, and I don't want to have
to track all those checked exceptions.
So I'd like to see more use of alternate languages on top
of the Java platform, with different goals and styles.
For example, I was really pleased to see the "Groovy" language
brought into the JCP. It is designed as a new
Java platform language,
but with its own goals and design center that are very
different from the classic Java language. Happiness!
My personal suspicion is that the Java language is good
for at least another 20 to 30 years, if we are careful in managing its
evolution. But I also expect that over time new research ideas will emerge and
slowly gain acceptance and at some point we'll want a new synthesis
that will create a great new simple language. And of course
we'll want to make sure that sparkling new language runs on the Java