Topic: Possible extension to enum
Author: Philip@storcomp.demon.co.uk (Philip Hugh Hunt)
Date: Thu, 11 Aug 1994 22:38:42 +0000 Raw View
I have thought of 2 possible extensions to enum, that i think would
be useful, and wonder what people think.
1. Inheritance
--------------
Allow an enumerated type to contain all the values of another enumerated
type, and add more values.
Example: Imagine a program to play chess. Enums for white and black
pieces:
enum WPiece { WPawn=1, WKnight, WBishop, WRook, WQueen, WKing };
enum BPiece { BPawn=7, BKnight, BBishop, BRook, BQueen, BKing };
A piece of either colour could be defined as:
enum Piece: WPiece, BPiece {};
The chessboard might be defined as a 12*12 array (2 squares off-board
border). Each square on the board is a SqValue, defined as:
enum SqValue: Piece { Empty, OffBoard };
If an enum inherits from another enum, the first value defined in the
new enum is 1 greater than the inherited value, unless it is defined
as being a specific value. (So in this case, Empty==BKing+1==13).
SqValue sq;
Piece p;
sq = p; // (1) legal
p = sq; // (2) illegal, should be p = Piece(sq);
Assignment to a less restictive type is allowed without explicit
conversion (1). Assignment to a more restrictive type requires explicit
conversion (2), unless 'Piece' is specified as implicit_conv (see below).
Advantages of inheritance
-------------------------
1. Natural and easy to understand syntax.
2. Allows you to specify more exactly what is and isn't a legal value
for a variable.
Disadvantages
-------------
1. Complicates the language
2. Allow enums to have implicit conversion
------------------------------------------
Enums always used to have implicit conversion to/from other integral
types in C. For some enumerated types this is meaningless (eg SqValue
above), for others it is more sensible (eg TokenType below). I
propose 2 new keywords (shock, horror) to determine whether conversion
should be implicit or explicit for a particular enumerated type:
'implicit_conv' and 'explicit_conv'. The default is explicit_conv. The
conversion-status specifier goes immediately before 'enum'.
An enum inherits the conversion status of its 1st inherited enum (eg
in the example above Piece inherits its conversion-status from WPiece).
Example showing implicit conversion:
implicit_conv enum TokenType {
/* values 1..127 are characters */
Identifier = 257,
IF, // 'if' reserved word
FOR,
WHILE,
PLUS_PLUS, // '++' operator
//...etc...
};
TokenType lex();
A lexical analyser lex() produces output in the form of tokens. If
the token is a single character (eg '['), its token value is the
value of the character. If the token is a reserved word, identifier,
etc, it has its own special value.
Another use might be in:
implicit_conv enum bool { false, true };
However 'bool' has already been defined as a keyword.
Advantages of specifiable conversion status
-------------------------------------------
1. For some enumerated types it is natural to allow values other than
those enumerated; for others it is not. This notation allows you
to specify *in the language* what sort of enum it is, allowing code
to be more self-documenting than it otherwise would be.
2. There could be a compiler flag (or debugger option) which checks
that explicit_conv enumerated types don't get assigned values for
which there is no enumeration, and complains if they do. This could
be useful for debugging.
Disadvantages
-------------
1. Introduction of new keywords might break existing code. IMO this
is unlikely. (About 0.4% probability that it will break a *single*
program [1]).
2. Some people see implicit conversion as inherently bad. (IMO these
are usually the same people who see 'goto' as inherently bad).
--
[1] If we assume 2,000,000 C++ programmer have written 100,000 lines of
code each, with 1 new identifier per 10 lines of code. Total number of
identifiers = 2*10^10.
'explicit_conv' has 13 characters. The probability of this existing in
a randomly-geneated identifier = (26*2+10+1)^13. However identifiers are
not random so I estimate it at 10^13.
Probability of preaking existing code = 2*10^10 / 10^13 = 0.2%
Multiply this by 2 as we also have 'implicit_conv'.
--
Phil Hunt
Author: kevlin@wslint.demon.co.uk (Kevlin Henney)
Date: Fri, 12 Aug 1994 12:47:41 +0000 Raw View
In article <776644722snz@storcomp.demon.co.uk>
Philip@storcomp.demon.co.uk "Philip Hugh Hunt" writes:
>I have thought of 2 possible extensions to enum, that i think would
>be useful, and wonder what people think.
>
>1. Inheritance
>--------------
This is a suggestion that pops up quite frequently. So I'm afraid to say
that you're not the first.
>Allow an enumerated type to contain all the values of another enumerated
>type, and add more values.
This does not conform w/ any existing definition of inheritance or subtyping.
An object of a subclass may contain more _attributes_ than its superclass,
but this is not the case here. There are as many or fewer objects that may
conform to a subtype than may conform to its supertype. What you are
proposing is the reverse.
>Example: Imagine a program to play chess. Enums for white and black
>pieces:
>
> enum WPiece { WPawn=1, WKnight, WBishop, WRook, WQueen, WKing };
> enum BPiece { BPawn=7, BKnight, BBishop, BRook, BQueen, BKing };
What if BPawn == 1?
>A piece of either colour could be defined as:
>
> enum Piece: WPiece, BPiece {};
>
>The chessboard might be defined as a 12*12 array (2 squares off-board
>border). Each square on the board is a SqValue, defined as:
>
> enum SqValue: Piece { Empty, OffBoard };
>
>If an enum inherits from another enum, the first value defined in the
>new enum is 1 greater than the inherited value, unless it is defined
>as being a specific value. (So in this case, Empty==BKing+1==13).
>
> SqValue sq;
> Piece p;
> sq = p; // (1) legal
> p = sq; // (2) illegal, should be p = Piece(sq);
>
>Assignment to a less restictive type is allowed without explicit
>conversion (1). Assignment to a more restrictive type requires explicit
>conversion (2), unless 'Piece' is specified as implicit_conv (see below).
Again, this goes against existing notions of inheritance. There are a
number of practical problems related to name clash resolution, and
what exactly inheritance means here, since it is typically restrictive.
You may also find that this particular problem is better solved using
classes - having enums for your pieces is a bit C-ish and implies that
you'll probably have a look-up table somewhere for their properties
rather than having them described by definition of virtual behaviour in
derived classes. I'm also not convinced by having additional names for
different coloured pieces ;-)
>Advantages of inheritance
>-------------------------
>
>1. Natural and easy to understand syntax.
Syntax is one thing, but I think you'll find the semantics a minefield.
>2. Allows you to specify more exactly what is and isn't a legal value
>for a variable.
So do classes - they can model objects that have almost built-in behaviour
if required.
>Disadvantages
>-------------
>
>1. Complicates the language
... a lot
In many ways the problem has already been solved by the addition of
classes to C giving C++ ;-)
>2. Allow enums to have implicit conversion
>------------------------------------------
>
>Enums always used to have implicit conversion to/from other integral
>types in C. For some enumerated types this is meaningless (eg SqValue
>above), for others it is more sensible (eg TokenType below). I
>propose 2 new keywords (shock, horror) to determine whether conversion
>should be implicit or explicit for a particular enumerated type:
>'implicit_conv' and 'explicit_conv'. The default is explicit_conv. The
>conversion-status specifier goes immediately before 'enum'.
>
>An enum inherits the conversion status of its 1st inherited enum (eg
>in the example above Piece inherits its conversion-status from WPiece).
>
>Example showing implicit conversion:
>
> implicit_conv enum TokenType {
> /* values 1..127 are characters */
> Identifier = 257,
> IF, // 'if' reserved word
> FOR,
> WHILE,
> PLUS_PLUS, // '++' operator
> //...etc...
> };
>
> TokenType lex();
>
>A lexical analyser lex() produces output in the form of tokens. If
>the token is a single character (eg '['), its token value is the
>value of the character. If the token is a reserved word, identifier,
>etc, it has its own special value.
>
>Another use might be in:
>
> implicit_conv enum bool { false, true };
>
>However 'bool' has already been defined as a keyword.
>
>Advantages of specifiable conversion status
>-------------------------------------------
>
>1. For some enumerated types it is natural to allow values other than
>those enumerated; for others it is not. This notation allows you
>to specify *in the language* what sort of enum it is, allowing code
>to be more self-documenting than it otherwise would be.
In that case, might I humbly suggest that such types are not _enumerated_?
>2. There could be a compiler flag (or debugger option) which checks
>that explicit_conv enumerated types don't get assigned values for
>which there is no enumeration, and complains if they do. This could
>be useful for debugging.
In principle we can have this feature now.
>Disadvantages
>-------------
>
>1. Introduction of new keywords might break existing code. IMO this
>is unlikely. (About 0.4% probability that it will break a *single*
>program [1]).
>
>2. Some people see implicit conversion as inherently bad. (IMO these
>are usually the same people who see 'goto' as inherently bad).
... and what about all the other disadvantages? Eg. increased complexity
in the language for no actual gain.
>--
>
>[1] If we assume 2,000,000 C++ programmer have written 100,000 lines of
>code each, with 1 new identifier per 10 lines of code. Total number of
>identifiers = 2*10^10.
>'explicit_conv' has 13 characters. The probability of this existing in
>a randomly-geneated identifier = (26*2+10+1)^13. However identifiers are
>not random so I estimate it at 10^13.
>Probability of preaking existing code = 2*10^10 / 10^13 = 0.2%
>Multiply this by 2 as we also have 'implicit_conv'.
Cute. But I prefer wangles myself.
>--
>Phil Hunt
The original C committee dithered over whether or not to include enums,
as did Stroustrup w/ C++ - he couldn't see that they were useful for
the programming styles that he wished to support, but included them and
tidied them up as they were inherited (sic) from C. IMHO, adding more bells
and whistles to them is quite a few steps in the wrong direction if not
backwards.
Just my 2*10e7n$.
--
Kevlin A P Henney
synonymicon is another word for thesaurus