HaXe enums are algebraic data types (ADTs). Your example in Haskell:
data Color3
= Red
| Green
| Blue
| Grey { v :: Int }
| Rgb { r, g, b :: Int }
| Alpha { a :: Int, col :: Color3 }
In either language, this type simply expresses that a Color3
has a few possible values—red, green, or blue; a grey value; an arbitrary RGB value; or a Color3
value with an additional alpha channel. The fact that some of these constructors take extra parameters should not be alarming. It is simply a terse closed analog to the open behaviour of inheritance:
class Color3 {}
class Red : Color3 {}
class Green : Color3 {}
class Blue : Color3 {}
class Grey : Color3 {
public var v:int;
public function Grey(v:int) {
this.v = v;
}
}
class Rgb : Color3 {
public var r:int, g:int, b:int;
public function Rgb(r:int, g:int, b:int) {
this.r = r;
this.g = g;
this.b = b;
}
}
class Alpha : Color3 {
public var a:int;
public var col:Color3;
public function Alpha(a:int, col:Color3) {
this.a = a;
this.col = col;
}
}
Here anyone can come along and add a new Color3
child class that may or may not respect the properties we want to enforce. With parameterised enums we have central control over all the constructors, and we also have pattern matching:
return switch (c) {
case Red: 0xFF0000;
case Green: 0x00FF00;
case Blue: 0x0000FF;
case Grey(v): (v << 16) | (v << 8) | v;
case Rgb(r,g,b): (r << 16) | (g << 8) | b;
case Alpha(a,c): (a << 24) | (toInt(c) & 0xFFFFFF);
}
Contrast the alternative of adding a toInt()
method to every subclass of Color3
. It would be much more code, leading to more potential for errors.
Note that this particular example isn’t great because a few of the constructors are redundant: Rgb
subsumes Red
, Green
, Blue
, and Grey
, and Alpha
can be applied to a colour that already has Alpha
, which may not be desirable.
Enum would be wrong way for this in JDK API which is supposed to serve wide variety of applications.
It would be also wrong in application development, unless the application is purposedly designed to serve a fixed, limited subset of languages - subset that is known at compile time - which, in turn, would hardly qualify as related to BCP-47.
This is because substantial attribute of BCP-47 is addressing an open-ended set of values:
Language tags are used to help identify languages, whether spoken, written, signed, or otherwise signaled, for the purpose of communication. This includes constructed and artificial languages but excludes languages not intended primarily for human communication, such as programming languages...
The ietf-languages list is an open list...
Above, in turn, makes it wrong fit for enum, which is intended to serve fixed, limited sets of values:
You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time - for example, the choices on a menu, command line flags, and so on...
Best Answer
I cannot think of any reason to require numeric values in a REST API. Use strings, and in your specification, identify what the valid values are.
If you want to go the extra mile and write enums (or equivalent) for a platform-specific client then go for it, but you will of course have to maintain it. If at all possible, you should make these API clients part of the same build process, or set your build system to automatically build the API clients whenever you do a release build. That way, a new version of the client is automatically available whenever you publicly release a new version of the API.
I realize this isn't necessarily easy to do, but such is the nature of maintaining platform-specific clients. That's why most maintainers don't do it. Oracle may need to do it but you probably don't. Twitter, GitHub, PayPal, etc. - they don't maintain "clients", just the API and its specs/documentation. Sometimes there will be open-source clients maintained by completely separate teams, but the owners of the service itself take no responsibility for them.
Typically an API client that is completely customized for a particular platform could more accurately be called an SDK. Treat it with that level of care and respect and the rest of the pieces should fall into place. Are you really prepared to maintain an SDK?