Have you considered reading?
By allowing any value of the underlying type, even if they were not values of the enum. The language most famous for this is obviously C:
enum foo { A, B, C };
int main() {
enum foo x = A;
printf("%d\n", x);
enum foo y = 42;
printf("%d\n", y);
}
This will print `0` and `42` (https://godbolt.org/z/Yq8qq5bzW), because C considers enums to be integral types and will thus implicitly convert to or from them. And as you can see from the link, there is no warning under `-Wall`. Clang will warn with `-Wassign-enum` (which is included in `-Weverything`), I don't think there's any way to make gcc complain about this.Now you might argue that this is C so obviously it fucks this up, however that C does this leads to further issues:
- For compatibility with C, C# enums have the same property. I don't know about you, but that surprised me a great deal since Java has type-safe enums (even if they're not sum types).
- Even more so, C++ added `enum class` in C++11, and obviously has inherited C's enums, but enum class still is not type safe, afaik the differences are that `enum class` is scoped (so in the snippet above you'd need `foo::A`) and it's not implicitly convertible with the underlying type. But it's still explicitly convertible (via a cast or list initialisation), meaning you can't assume a caller will remain within the enum.
Check the upvotes on my comment.
[1] https://en.wikibooks.org/wiki/Ada_Programming/Types/Enumerat...
> We use enums heavily to force devs who use our code into good choices
the note is that this is very much language-dependent and there are languages which get it very, very wrong.
> And I'm sure there are languages that do enums "properly", but it's always C/C++ that is referenced.
That makes no sense, the original comment obviously assumes a language which does it "properly".
Beware, tho, that with many languages today you’re not really doing that even when they advertise enums e.g. in both C# and C++, enums are not type-safe (not even `enum class`). Iota is, at least, a fair acknowledgement of that.
> with a FromString() function
That seems like way a step too far, is there any such “default method” today? And I don’t think Go has any sort of return-type overloading does it?