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?

+3


source to share


2 answers


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.

+1


source


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() { }

      

+1


source







All Articles