And pointing out missing features in a programming language is just about the weakest criticism possible.
Piling on lots of features is easy and fun. That's why almost all language designers do it. Most popular languages destroy themselves with features.
Rust is in the process of gaining every single feature anyone can imagine. Following C++ right off the complexity cliff.
Go is one of the very few languages to show incredible restraint in adding features because its designers understood the combinatorial complexity problem, among other things.
Not having unnecessary features is one of the best features of Go.
In a business environment, this is a obvious win.
The results are in for Go. It's already one of the most successful programming languages in history any way you measure it.
Of course Go should continue to improve and add features where the value outweighs the increased complexity. That's how it eventually got generic functions and other features.
And if I had to guess, it doesn't have enums so that it can remain flexible when serializing/deserializing enum-like types over the wire. Imagine you can't parse an incoming payload containing an enum field because your service is one version older than the one that extended the enum type (or the enum type is defined in a package dep... you get the idea). Enums are actually a terrible idea now that I think about it.
To me, golang symbolizes the shift of philosophy of Google as a company. It changed from "it's a smart nerd company for smart nerd people" to "golang will allow us to hire cheaper devs because golang will prevent them from making mistakes". I mean, this makes sense from business perspective, I won't deny this fact, but it's the programming equivalent of Ferrari making a SUV: tremendously profitable, but sad to see.
BTW
> golang doesn't support overloading because overloading is bad. Having said that, it's 'go', not 'golang', like the verb 'go', which already has a thousand meanings depending on the context
I find that hilarious
There are some "design-by-committee" weirdnesses, but if you squint a bit it's perfect.
I know that many people love Go, and I respect that, but I was never able to grasp its appeal (despite my two-year stint as a professional Go programmer). To me, the philosophy of Go seems to prioritize simplicity in the language at the cost of making software written in it more complex. Writing in Go often felt like a constant exercise in haveing to reinvent even the simplest things.
I worked in Java / C# with tons of interfaces all over the place, getter / setter in every files.
The constant gotchas in golang indicate that it does not fit in people's heads within a few months.
One of the tools I work on in my spare time is a Poker calculator that uses enums extensively for things like suits and hand strengths (flush, full house, etc.). This program doesn't connect to the internet in any way. But I hadn't considered that someone might come along and force me to serialize these poker hands and send them over the wire and change the number of suits and ranks in a deck of cards so that it creates incompatibilities. I guess I should go back and rewrite my code to remove those enums, since that's going to be a problem.
So you'd define `type Suit int` and have constants of type Suit that are `const DIAMONDS Suit = 0` ... `const SPADES Suit = 3`.
Go just doesn't have first-class enums with cardinality less than an int, like Java would. Which means you could have a Suit type variable with a value of 4 or 9000, because Suit serializes/deserializes as an int, not some custom string representation as in other languages.
import "fmt"
// Define an enumeration for status type Status int
const ( Pending Status = iota InProgress Completed Failed )
func (s Status) String() string { return [...]string{"Pending", "InProgress", "Completed", "Failed"}[s] }
func main() { var s Status = InProgress fmt.Println(s) // Output: InProgress }
const ( Pending Status = iota InProgress Completed Cancelled Failed )
func (s Status) String() string { return [...]string{"Pending", "InProgress", "Completed", "Failed"}[s] }
func main() { var s Status = Cancelled fmt.Println(s) // Output: ??
If the compiler - not some linter - protests that the list of names is different from the number of items in the enum, then I think this is at least a half-decent design of an enum type. Not a great one (because the author still had to repeat the names), but at least something that isn't a fundamentally broken design of an enum type.
But if the compiler is silent, and the output of the Println(Cancelled) is "Failed" then I'm not angry, I'm disappointed.
In your suggested method it doesn’t even catch that case and provide an error if the value isn’t in the range.
I think parent should be using `stringer` [2] instead.
I didn't say anything along those lines, in fact I was commenting generally about this issue that you guys and the other commenters mentioned.
I was just suggesting a solution to the the problem stated.
Only one step better than Assembly or Fortran.