[comp.lang.eiffel] Enumerations in Oberon

brandis@inf.ethz.ch (Marc Brandis) (01/04/91)

In article <2339@enea.se> sommar@enea.se (Erland Sommarskog) writes:
>Also sprach Richard Bielak (richieb@bony1.UUCP):
>>Although I'm not sure exactly why, but enumeration type present some
>>difficult problems to the compiler when types are extended through
>>inheritance. My evidence? Look at OBERON, latest language from N.
>>Wirth, it does not have enumerated types.
>
>As I recall Wirth's paper, the reason he gave for removing
>enumerates was that he wanted to keep down compiler in size.
>A good reason? Obsession, if you ask me. (And I recall that
>enumeration types would not be a problem in Oberon. All you
>can extend is record types. 

This is certainly wrong, and the evidence that Richard Bielak found is correct.
Let me cite what Wirth said in "From Modula to Oberon".

	Enumeration types appear to be a simple enough feature to be uncontro-
	versial. However, they defy extensibility over module boundaries. 
	Either a facility to extend given enumeration types has to be 
	introduced, or they have to be dropped. A reason in favour of the
	latter, radical solution was the observation that in a growing number
	of programs the indiscriminate use of enumerations (and subranges) has
	led to a type explosion that contributed not to program clarity but
	rather to verbosity. In connection with import and export, enumerations
	give rise to the exceptional rule that the import of a type identifier
	also causes the (automatic) import of all associated constant 
	identifiers. This exceptional rule defies conceptual simplicity and
	causes unpleasant problems for the implementor.

When you look at where enumerations are used in programs, you will notice that
in a extensible software environment like Oberon, you definitely want to be
able to extend these constructs. You can easily do this when using INTEGERS
together with constants (just define some additional constants), but it is not
that easy when having enumerations in the language. 

Note that when you have to do it with INTEGERS and constant, the semantics are
obvious. If you implement extensible enumeration types, they are not so
obvious. First, in Oberon, an instance of an extended type is always also an
instance of the base type. The value of this instance seen as the base type
is well-defined by the concept of projection. Now, what would the value of an
instance of an extended type seen as the base type? E.g.

	TYPE
	  Colors = (red, green, blue);
	  MoreColors = (Colors)(yellow);

Now assume that you have an instance of MoreColors with the value yellow. What
is now the value of this variable when seen as a Colors?

Another problem is how to implement type checks and type guards.

All these problems have been discussed, and there are solutions to all of them,
but it is not clear whether the advantages of having enumeration types out-
weights the conceptual complications on several fronts.

Last but not least, there is a big problem in the import of such enumerated
types. When you import an enumerated type, all its associated constants become
imported as well and are put into the outermost scope. If two modules use
the same constant name in an enumeration, and both modules are imported by
another module, you get a name conflict. Of course, you can solve the name
conflict by using type information from the context in which the constant is
used, but it is not easy to do.

To your statement about smaller and simpler compilers, and Wirth's obsession,
I have to add something. First, as you may have found yourself: smaller and
simpler programs are easier to maintain and to write and contain less bugs!
I am using several implementations of Oberon myself, and I have to say that
compiler bugs are found very (!!!) rarely. And there has never been something
like a list of known bugs, as every bug was so easy to fix that it could be 
done in less than a day. (Do not flame me on this, I know that this is not
possible in a commercial environment. But I am convinced that bug-fixing in
these multiple-hundred-thousands of lines compilers is much harder than in
the less than 5000 lines Oberon compilers).

Wirth's idea is to weight cost against win, as every good engineer should do.
I think that it is time for the software industry to recognize that programs
do not become better by adding tons of features. In fact, when you browse 
through journals like BYTE or PC Journal, you will see that many power users
(like Pournelle or Dvorak) would love to go back to some simple and small
programs that they used in their CP/M or early DOS time instead of having to
use the feature- and bug-loaded new programs, which are about an order of
magnitude slower on a machine that is an order of magnitude faster, compared
to their old programs.

The same is true for programming languages.

As this does not have too much to do with Eiffel, followups directed to
comp.lang.misc.


Marc-Michael Brandis
Computer Systems Laboratory, ETH-Zentrum (Swiss Federal Institute of Technology)
CH-8092 Zurich, Switzerland
email: brandis@inf.ethz.ch