bertrand@eiffel.UUCP (Bertrand Meyer) (06/05/89)
On the evolution of programming languages,
with particular attention to the evolution of Eiffel
Bertrand Meyer, June 4-5, 1989
This draft note is based on ideas presented at the
International Eiffel Conference in Paris on April 21.
From the initial design to the asymptote
The programming literature contains quite a few
references on the subject of programming language design. A
seminal article, more quoted than heeded, is Hoare's ``Hints
on Programming Language Design'' (POPL 1973). The subject
of evolution after initial design has received less
attention. Here are a few thoughts and their application to
Eiffel.
A key criterion in language design is simplicity of the
result. Even if initially satisfied, this property is
difficult to maintain in light of increased usage of the
language by diverse groups tackling varied applications.
The standard counter-example - target of the most
frequent cheap shots - is PL/I, commonly blasted for its
complexity. If you want to get an easy laugh out of an
audience of computer scientists, or to williehorton someone
else's design, evoking PL/I is a sure win. Abusing this
not-too-young language is not wholly unfair but rather
facile. I see much worse horror stories in languages that
initially were reasonably small but then started to develop
carcinomatous cells in all directions.
How can we reconcile the demands of large-scale
software development, and the myriad practical problems
which they raise, with the constant concern for maintained
simplicity and consistency?
To compound the difficulty, the topic of programming
languages and their design seems to provoke an inordinate
number of suggestions from a group - software engineers - of
inordinately opinionated people. It is striking to see how
many of these ideas are in fact excellent; but this does not
mean that they should all be included!
First they may raise subtle or major incompatibilities
with other language features; but even if this is not the
case they most often will make the language more complex. In
each case the designer must weigh the evidence: is the
purported benefit really worth the increase in complexity? I
have found that in nine out of ten cases the answer is no.
Again this usually is no reflection on the quality of the
idea. But the designer's primary responsibility is to keep
in mind the elegance of the overall picture.
In the current state of Eiffel (and I assume this
applies to any recent language that is now at a similar
stage of its development), there is one other and totally
new element, incredibly exciting and at the same time
somewhat frightening: the net. Electronic mail and forums
such as this one mean that hundreds of people can react in a
few hours to the latest announcements, ideas, proposals,
opinions and suggestions. For Eiffel this has been a
tremendous benefit. The number of people who have sent
public or (more often) private comments is incomparably
greater than what it would have been just a few years ago.
Even Ada, undoubtedly the language most widely and
thoroughly debated before its final design, was born before
network access became available on a grand scale, and did
not benefit from the unique combination of breadth, depth
and timeliness made possible by the technology of the late
nineteen-eighties.
The contribution of the net has been considerable. (To
add a personal note, let me use this opportunity to
apologize to all the people who wrote to me recently and got
no answers. I simply cannot keep up with my mail these
days, and I am not too good at sending polite ``pro forma''
answers. I do read carefully everything that gets to me,
however.) Add to that co-workers, users, course
participants, colleagues in panels at conferences, and you
get a constant influx of new ideas.
What can one do in such a context? The best tactics I
know is to say ``no'', bury one's head in the sand and
emerge some time later to see if there is still anyone
around. This is not arrogance but preservation of one's
mental sanity. For Eiffel, the basic policy is utmost
conservatism. Do not change anything unless you cannot find
any more arguments for the status quo. Because of this,
Eiffel is still extremely close to the language which was
designed in early September of 1985.
But saying ``no'' most of the time is not an excuse for
not listening. *Almost any single criticism or suggestion
contains something useful for the language designer*. This
includes comments by novices as well as expert users. But
most of the time you must go beyond what the comment says.
In particular you must usually see through a ``solution''
that is suggested to you, and understand what it obscures:
the real problem.
Finding the solution is your responsibility, the one
you cannot abdicate. Integrity of the entire design can only
be achieved and maintained by one person or a small group,
for whom the language is not just a means but also an end.
The users and critics see many things that you don't; they
(the users at least) are the ones who have to live with the
language day in and day out. But you can't expect them to do
your job. (Sometimes, of course, they do: someone will come
up with just the right suggestion. Then you can be really
grateful.)
So there are deep and shallow comments but almost no
useless ones. Sometimes the solution simply resides in
better documentation. Often it lies in a tool, not in any
language change.
Extensions through the library
In a language supporting libraries, it is often
possible and desirable to provide a new feature through a
library facility rather than through a language change.
For example, Eiffel 2.2 facilities such as the ``out''
function (which produces a printable image of any value or
object) or the ``copy'' and ``deep_copy'' procedures (which
copy any object), although initially envisioned as language
additions, were in fact implemented as normal features in a
standard library class, ANY, now inherited by every class.
A cynic might question the benefit of extending the
library to keep the language simple. Indeed, tough problems
of consistency and simplicity (discussed in previous
messages) do arise for the library. There is an important
difference, however: one of level. The library as well as
any user application are defined with respect to the basis
provided by the language. Because everything else relies on
it, this basis must be kept simple at all costs. Undue
complexity in the library should be avoided, but the
consequences are less grave.
Mathematical theories provide the appropriate
comparison. Adding a language construct is like adding an
axiom, certainly not a decision to be taken lightly. Adding
a library class or routine is simply like adding another
theorem, inferred from the current axioms.
Changing the language
When everything else fails, the language is really
under fire. Something must be done.
When this happens - and only as a last resort - the
tough conservative temporarily softens his stance. There are
two cases, which are really different: extending the
language and (supreme horror) invalidating an existing part.
They will be addressed separately.
Extensions
Extensions are the language designer's secret vice, the
dieter's chocolate mousse on the evening of his birthday,
the key that is available for just one night to open the
chastity belt.
After much remonstrance and lobbying you finally
realize what many users of the language had known for a long
time: that some useful type of computation is harder to
express than it should be. You know it's extension season.
There is one and only one kind of acceptable language
extension, and that is the extension that dawns on you with
the sudden self-evidence of morning mist. You may get the
idea yourself (and that is good for your ego) while brushing
your teeth and thinking of something else; or (more often)
it may be suggested out of the blue by someone else at the
end of a three-hour meetings - one among a seemingly endless
series of such meetings. All were bored and tired and
thinking about home, but suddenly everyone knows that the
solution is there and everyone asks: ``But why didn't we
think of it before?'' For most often the simplest idea is
the last one to suggest itself. But when it is indeed *the*
solution, then no doubt remains. It must be simple, elegant,
explainable to any competent user of the language in a
minute or two. It must provide a complete solution to a real
problem. It must fit perfectly within the spirit and letter
of the rest of the language; almost always, in fact, it will
unexpectedly solve one or more other problems. It must not
have any dark sides or raise any unanswerable questions.
And because software engineering is engineering, and
unimplemented ideas are worth little more than the
whiteboard marker with serves to sketch them, you must see
the implementation technique. The implementors' group in the
corner of the room is grumbling, of course - how good would
a nongrumbling implementor be? - but you and they see that
they can do it.
When this happens, then there is only one thing to do:
go home and forget about it all until the next morning. For
in most cases it will be a false alarm. It it still looks
good after a whole night, then the current month may not
have been lost altogether.
Introducing incompatibilities
What happens if you realize that some existing language
feature, that may be used by thousands of applications out
in the field could have been designed better? Obviously,
unless this occurs extremely rarely, the language and its
designer are in trouble.
We have been fortunate in the history of Eiffel to have
mostly been preserved from such unpleasant situations. Yet
sooner or later one is bound to occur. Recently, for
example, we have come to realize that the syntax for object
creation in Eiffel could be made more elegant, with a clear
if small semantic benefit.
This is an interesting case because (fortunately!) the
change is not essential. A decision either way will have no
major impact on the language's progress and on the users'
ability to tackle any particular problem. The change would
just make their lives somewhat easier in some specific
cases, and the overall language design more clean. (The
particular language issue alluded here will be described in
a message to be posted by mid-July, and there will be ample
time for discussion before anything is cast in concrete.
Although design by vote is clearly an absurd idea, no change
to existing constructs should ever be implemented without a
broad airing of educated opinions.)
What do you do in such a case? The accepted wisdom is
to forget about it. This is also the path of least
resistance. A previous message (about the libraries) talked
about the GAIB (Guardian Angel of the Installed Base) and
the DECHOP (Devil of Eternal Compatibility with the Horrors
of the Past), whose constant advice is to preserve the
tranquillity of current users. The long-term price, however,
is languages that carry forever the ugly remnants of another
age.
I tend to go for the other policy, which says: if
really you have made a mistake, then admit it and correct
it; and the sooner the better. A number of stringent
conditions must be satisfied:
+
There must be wide agreement that the new solution is
significantly better than the original one. It must
not entail any negative consequence other than its
incompatibility.
+
The implementors MUST provide an automatic conversion
mechanism for existing software. This is an essential
requirement, for which the only acceptable exception
seems to be the introduction of a new keyword. (Here
the incompatibility is for programs that used the
keyword as identifier. Unless the keyword is one that
is known to be commonly chosen as identifier, it
seems acceptable to rely on programmers to perform
any needed changes in their software.)
+
Everything must be synchronized: software with the
new feature, documentation, etc.
If these conditions are met, then I believe one should
cut one's losses and go ahead with the change.
The Eiffel perspective
Where does Eiffel stand in the language design and
evolution cycle, and where is it going?
The general feeling of the participants at the recent
Paris Conference seemed to be that the language is basically
all right as it is. It was particularly interesting that
this opinion was expressed by the presenter of a paper that
described a 2,000-class, 350,000-line application (who
otherwise criticized several aspects of the current
implementation). Criticisms and suggestions pertaining to
the language were expressed, of course, by various
presenters; but it was comforting to see that most of them
were appropriately addressed by the 2.2 extensions.
My biased view is that the basic language will not
change much from now. Especially with 2.2, it is hard to
see what important facility might still be lacking. (The
question of parallelism is not covered in this analysis.
There will be a posting on this soon.) Version 3.0,
scheduled for the end of this year, should provide an
opportunity to clean up a few points, as mentioned above.
No significant extension is planned at present.
[Incidentally, some people reading these lines
might be surprised at the lack of reference so far
to alleged problems with type safety in Eiffel,
mentioned in postings to this group and even in a
paper at the forthcoming ECOOP conference. But
contrary to what has been asserted there is no
type consistency problem in the language. Two
problems are: (1) Rare but real errors that are
not caught by the current implementation. (2)
Insufficient explanations in my OOSC book, and
delays in the paper I announced on the subject.
There was no time to fix these problems for 2.2,
but they will be corrected for the next release.]
My hope is that with 3.0 the base language will be
close to the asymptote. This, incidentally, means that if
you really feel strongly about some aspects of Eiffel the
summer and early Fall of 1989 are the right time to make
your voice heard.
What happens next? In the software field, predictions
beyond six months tend to be wishful thinking at best. What
I would hope to see is a stable language not directly under
Interactive's sole technical control. (This, by the way, is
strictly a discussion of technical issues and does not
address any proprietary, trademark or other non-technical
concerns.) Until the end of this year it seems appropriate
that Interactive, and more specifically I, should remain
``in charge'' technically. But after that a measure of
success will be our ability to transfer control over the
language's evolution to some other body. What this body will
be I do not know; perhaps a standardizing committee, or some
implementors' council. My colleagues and I would
undoubtedly play an active role but would by no means be the
only members.
To end with a personal note, let me thank all those who
corresponded with us during the past few months and helped
shape version 2.2. The quality of the interaction has been
tremendous and I learned a lot. I take all the blame for
the deficiencies, of course, but it is appropriate to
express my gratitude to, among many others (and not counting
employees of Interactive), John Anderson, David Butler,
Paul Dubois, Serge Granik, Jim Gish, Roger Rousseau,
Andreas Schramm, Norman Shelley, Erland Sommarskog. I have
that unescapable feeling that as soon as I have posted this
I will remember the key names that I forgot. Please accept
my apologies in advance and blame the omissions on the
author's incurable absent-mindedness.
--
-- Bertrand Meyer
bertrand@eiffel.com