Is there a programming language with extensible enums?
Many object-oriented languages allow classes to be extended in this way:
class Animal {}
class Cat extends Animal {}
class Dog extends Animal {}
However, when using enums, there are cases where the opposite functionality is desired. For example:
enum CatAction {
meow, eat, sleep
}
enum DogAction {
bark, fetch, eat, sleep
}
enum AnimalAction {
eat, sleep
}
There is some redundancy here. AnimalAction
should be CatAction
, because if an arbitrary Animal
can do an action, then a Cat
can do it by definition. However, even languages with multiple inheritance do not allow definition enum AnimalAction extends CatAction, DogAction {}
, and furthermore this syntax does not avoid redundancy.
This can be corrected with generalizes
or a similar keyword.
enum AnimalAction {
eat, sleep
}
enum CatAction generalizes AnimalAction {
meow
}
enum DogAction generalizes AnimalAction {
bark, fetch
}
This functionality also makes some templates more useful:
enum Direction2D {
North, East, South, West
}
enum Direction3D generalizes Direction2D {
Up, Down
}
Do any programming languages support this functionality?
source to share
OCaml's polymorphic variants are close (although unlike enums, they are not numeric).
Here's an example:
type animal_action = [`Eat | `Sleep]
type cat_action = [animal_action | `Meow]
type dog_action = [animal_action | `Woof]
You can have multiple inclusions, but this is an inclusion: this results in the concatenation of the constructors in cat_action
and dog_action
.
type catdog_action = [cat_action | dog_action]
(* [`Eat | `Sleep | `Meow | `Woof] : that is, not what you wanted. *)
Polymorphic variants are actually a slightly more complex feature than this example suggests, but I don't think going into details will help answer your question.
source to share
C ++ can in my opinion.
struct Animal{
enum{
eat,
sleep
};
};
struct Cat : Animal{
enum{
meow,
glare,
hiss
};
};
struct Dog : Animal{
enum{
bark,
fetch,
peeOnCarpet
};
};
The enumeration values are in the same scope as the enumeration is declared. The first element of each enum, however, starts at zero, so if you don't have specific animal / derivative functions you might want to make sure each is unique.
You can solve this problem by adding a marker to each base class, I'm not sure if I like this but it works.
This code was written for Arduino (C ++).
struct Animal{
enum Action{
eat,
sleep,
die,
end
};
};
struct Dog : Animal{
enum Action{
bark = Animal::Action::end,
fetch,
peeOnCarpet
};
};
void setup() {
Dog d;
Serial.begin(9600);
Serial.println( "Values: " );
Serial.println( d.eat, DEC );
Serial.println( d.sleep, DEC );
Serial.println( d.die, DEC );
Serial.println( d.bark, DEC );
Serial.println( d.fetch, DEC );
Serial.println( d.peeOnCarpet, DEC );
}
void loop() { }
source to share