4 ms·
C++ programmer here. I was about to start a deep dive into Go today. Hearing there are no enums is giving me serious pause. How do large systems (e.g. Docker?)
by bravogamma 4y ago
C++ programmer here. I was about to start a deep dive into Go today. Hearing there are no enums is giving me serious pause. How do large systems (e.g. Docker?) deal with this?
- randomdata 4y agoIt has enums, but they are C-style enums rather than sum types. Which stands to reason given that C and Go were born to the same father.
- masklinn 4y ago> It has enums, but they are C-style enums rather than sum types. It doesn't. The closest it has is TFA's second example: type FlagID int const ( FooBar FlagID = iota FizzBuzz ) which is the underlying behaviour of C enums, but not actually that. Crucially it does not at any point hint or imply the set could be in any way closed. That it doesn't have C-style enums is a point in its favour, I would say. Not much of a point, mind, but still...
- randomdata 4y ago> It doesn't. It does. By definition, an enum is simply a set of named values, which you code example provides, and is behaviourally the same as C. > it does not at any point hint or imply the set could be in any way closed. While true, that is a feature of sum types, which I already indicated Go does not have. This is slightly different to enums.
- morelisp 4y agoIn C the enum declaration is - by idiom and also syntax - contained a single declaration. You can construct values outside those, but as a default assumption the compiler/linter has a reasonable list of values to claim "these are the enum values which need handling". In Go the values are not in a single declaration, and not even in a single TU. The strongest hint that this is an enum and not some other kind of integral newtype is the use of `iota` on the first declaration, but `iota` is also used for other purposes. You're technically correct that they're "behaviorally the same", but declaration structures matter a lot.
- randomdata 4y ago> but `iota` is also used for other purposes. According to the Go spec[1] iota exists specifically for enum generation. The closure of the enum is also defined. There is no other intended purpose. If a developer has found a new way to overload it in some new way they can equally do the same in C, so that is moot. Enums are not sum types in either language, with no expectation of behaving like sum types, there is no debate about that. They are simply enums. [1] https://go.dev/ref/spec#Iota https://go.dev/ref/spec#Iota
- masklinn 4y ago> According to the Go spec[1] iota exists specifically for enum generation. This assertion is nowhere in the Go spec, not even implicitly. `iota` is a convenience sequence generator, it is no more "specifically for enum generation" than sqlite's AUTOINCREMENT qualifier is. Or excel's cell-sequencing system. Further demonstrating that the goal was not to replicate C enums, iota can not be advanced manually save by adding intermediate discarded case. > If a developer has found a new way to overload it in some new way they can equally do the same in C No, they can not, literally the second example of your link has to be written and maintained entirely by hand in C, to say nothing of the second example block. > Enums are not sum types in either language, with no expectation of behaving like sum types, there is no debate about that. They are simply enums. Go still does not have enums, and your generalised statements about enumerated types remain incorrect regardless of sum types.
- randomdata 4y ago> This assertion is nowhere in the Go spec, not even implicitly. The first line explicitly defines their use for defining enums. The only way it could be more clear would be to define enum, but that should be unnecessary given that the definition is usually well established, although certainly a couple of languages have tried to muddy those waters in recent times. > `iota` is a convenience sequence generator More importantly, it defines a set of values. The set is what differentiates an enumeration from a general bag of constants. C reaches for a enum keyword instead, but they achieve the same result of establishing a set. > Go still does not have enums It has enums. It doesn't have sum types. Yes, some languages call sum types enums, which is no doubt where your confusion lies.
- nicoburns 4y agoIt’s also a feature of enums in languages like Java which don’t provide full sum types.
- vips7L 4y agoJava does provide a form of sum types via sealed classes, but they’re definitely not like TypeScript’s: type A = string | number;
- masklinn 4y ago> It does. No. > By definition, an enum is simply a set of named values That is not the definition of "an enum", no. "an enum" does not imply a complete absence of any sort of type safety. "a C-style enum" might, but that is not the distinguishing characteristic of C-style enums, the lying is, otherwise literally every language which has constants has C-style enums, including every language with sum types. > and is behaviourally the same as C. Except for all the ways in which C enums mislead users into assuming any sort of non-existent type-safety guarantees. There is a critical distinction between "C-style enum", aka a misleading pile of garbage, and "just a bunch of constants". The latter is what Go provides. > While true, that is a feature of sum types That is not correct. For instance Java enums are not sum types, but are a type-safe, closed, set of values.
- randomdata 4y ago> "an enum" does not imply a complete absence of any sort of type safety. Sum types are where you expect to find type safety. Some languages call sum types enums, which I expect is where the confusion lies. Neither Go nor C have sum types. > literally every language which has constants has C-style enums I think that ultimately that's a fair assertion, but one might argue that the definition does imply some kind of defined set. Both C and Go define syntax for characterizing enums in an established set which the machine can determine where the set boundaries lie. A language with only constants relies on human interpretation of what defines the set. > For instance Java enums are not sum types, but are a type-safe, closed, set of values. That's a sum type, also known as a tagged union. Neither Go nor C has those, as has been established multiple times now.
- Splizard 4y agoGo 1.18 supports type-safe enums and sum types. It takes 300loc to implement.
- Splizard 4y agoNo, it does. Go 1.18 supports closed enums.