Live data from Hacker News

Go Enums Suck

zarl.dev

111–120 of 244 posts

Re: Go Enums Suck

#111
post #13

A thing that so many enum solutions miss is that you have to have a path for a value outside of the current definition, or you lose a lot of flexibility in compatibility with any data that crosses wires or disks. Sounds fine for a lot of cases, of course, but in a world of mixed deployment fleets working on data, you pretty much have to have a way to allow a value that is not part of your current definition, or you a…

>> Sounds fine for a lot of cases, of course, but in a world of mixed deployment fleets working on data, you pretty much have to have a way to allow a value that is not part of your current definition, or you are basically placing a "poison pill" on your system. I had the joy of a numeric ID (an int) getting a B added to the end of it to distinguish the product as being the "same" but sourced from another vendor... (…

I found this lesson out the hard way by finding that a new "status" had been added to our service and blew up some of our monitoring code. Since our monitoring code was still correct for the cases that they were checking for, and had default clauses to note things that were not relevant, we were crashing purely because I had coded it to convert the incoming value into a java enum. Oops...

Re: Go Enums Suck

#112
post #48
post #23

Earlier quoted context omitted.

I'm not bent out of shape about go enum's like the OP. However when it comes to writing and reading data over networks or disk io a naked enum was never going to work anyway, not really. Then you turn to protobuf etc so one has a cross os/arch/cpu interoperability

I don't disagree, I don't think. Just wanting to float a reason simpler enums are usually preferred. In particular, you likely want to use the enum to restrict what values you will introduce into a system. You often, sadly, cannot use them to restrict what values are actually there. Which is why the place you pass them will see the raw int.

Yeah, but then should structs ever have a bounded size? Someone might well have gone and done did added a couple of fields to a struct over the wire.

Re: Go Enums Suck

#113
post #80

> Go doesn’t technially have Enums and it is a missing feature in my book but there is a Go idiomatic way to achieve roughly the same thing. Oh, so it's a lot like Python then. > This is fine however it is nothing but an integer under the covers this means what we actually have is: Oh, so it's a lot like C++ then. > But what you notice here is we have no string representation of these Enums so we have to build that o…

Go is in this weird middle ground where it's modeled after C, so it's got things like no enums, return codes for errors, mutable everything, nulls, and pointers (that don't support arithmetic, so it's really just this "*" sigil that you have to remember to use sometimes), but it's also fully garbage collected and has built-in, stackful green threads. I have no idea what it's actually trying to be.

C does have enums. Not trying to detract from your point, which I agree with, but enums are definitely a thing, which C has.

Re: Go Enums Suck

#114
post #94

func (o Operation) IsValid() bool { if o == Unknown { return false } return true } Why, oh why don't people just write return o != Unknown This is so common in the code that I'm seeing on the Internet, on GitHub etc. Is it because people don't understand booleans?

A good linter can help people see where their code isn't concise and give nudges toward better style. Clearly, being concise can sometimes mean being opaque, but in this case it's not, the boilerplate dilutes the meaning without adding value.

Go was developed as a highly opinionated language in which this style of imperative code is apparently preferred. Similarly, the ternary operator shines as a way to use a single assignment to obtain a value that follows from a concise boolean expression, but the ternary operator is wholly omitted from Golang.

Although, being opinionated is not in itself a bad thing. If you want to create something, it helps to have a viewpoint that gives you something to say.

Re: Go Enums Suck

#115
post #84

It's actually the coolest thing about Go enums, that they just it – enums. Developers with a background in other languages assume all enums' use cases need string representation. Well, no. They are needed sometimes, but not always. The same with the ability to pass int to the enum. Author says: > Anywhere that accepts an Operation Enum type will just as happily accept an int. Well, this is simply not true. [1] You'll…

>> Anywhere that accepts an Operation Enum type will just as happily accept an int.

>Well, this is simply not true.

As comment above [1] pointed out `printOperation(2)` is still valid.

[1] https://news.ycombinator.com/item?id=39565640

Re: Go Enums Suck

#116

Earlier quoted context omitted.

> Go has constants That's literally what enums are: A set of named constants. You might be thinking of what is traditionally known as sum types, which some people have recently started calling enums[1]. Indeed, Go does not have sum types. [1] Presumably because of Rust using the wrong term when specifying its sum types

is there any further information on why Rust and other recent languages have started using `enum` to refer to sum types? I don't use Rust or TypeScript (edit: apparently TS doesn't have this, my memory is bad) or any of those languages and it's been very strange to see this redefinition occur

My best guess is Java.

Edit: I guess if you've never seen that this is, uh, controversial. Or something. Anyway, Java enums are full-strength classes, look at the planet example here https://docs.oracle.com/javase/tutorial/java/javaOO/enum.htm...

This is more like a Rust enum than a C one, I think you'll find.

Re: Go Enums Suck

#117

It has always been surprising to me how primitive Go really is, for no really good reason. I understand the evolution of C, it made perfect sense back when it was invented. And the limitations were necessary due to the wide array of architectures and extremely limited computers of the time in every dimension (CPU speed, IO speed, RAM size, disk size, etc). Many of those dimensions have been improved by several orders…

You're right.

Go is not simple, it is idiotically designed to deliberately exclude common sense features that ironically makes it less simple and more error prone to code in and read Go.

Other languages are objectively better than Go for every imaginable use case. Rust is better for embedded. Kotlin is better for back end. I could go on.

The creator of Go is very open and candid that he thinks his target audience, Google Engineers, are too stupid to use "advanced" features like oh I don't know, sane error handling? and any number of basic things other languages have.

I know how cringe it is to start flame wars about programming languages, but srsly, Go, PHP, Perl, JS and a few others really are objectively worse (for every context and use case) than widely used alternatives.

Re: Go Enums Suck

#118
post #74

Earlier quoted context omitted.

I've heard this before, but I have a struggle understanding the abstraction. I make heavy use of rust and Python enums (Are they both misnamed?) Those + structs are generally the base of how I structure code. The "enums" in the article also seem to be of the same intent. Is this a "no true Scotsman" scenario? Some research implies the difference is a True Enum involves integer mapping, while a Sum Type is about a typ…

Enumerations back to integers. Enumerations can have iterators written on them that exhaustively enumerate the possible values. (Sum types either have no such enumeration at all, or in general, they're useless, so you don't see them.) Enumerations can be represented by a canonical and small set of strings, if you want a string backing them. This is what an enumeration is, partially because that's precisely what the w…

This still seems to point towards Rust's enums being both, no?

Example: For a network protocol, see the first code sample I posted.

For a `.Next()`, add the method. (I did this recently)

Regarding sum types into a network not working, this again sounds like the wrapped enums. One way to do this is use an integer for the enum variant at index 0, and conditionally assign bytes of an appropriate size based on the type wrapped for the next set of bytes.

Re: Go Enums Suck

#119

It has always been surprising to me how primitive Go really is, for no really good reason. I understand the evolution of C, it made perfect sense back when it was invented. And the limitations were necessary due to the wide array of architectures and extremely limited computers of the time in every dimension (CPU speed, IO speed, RAM size, disk size, etc). Many of those dimensions have been improved by several orders…

Simplicity is a feature. Sure, how complicated can effective enums really be, but Go's general philosophy is to think hard (& sometimes for a long time) before adding every bell and whistle. I have a far easier time delving in to previously unknown Go code for the first time compared to something like Scala (or even Java). Go is a solid language for those who value that and want to enable the experience for others.

Simplicity can be taken too far. Take this to its logical close cousin and you would have Forth or Basic.

Also, we have been doing computer language design for quite awhile now. This isn’t a new frontier. The deficiencies in Go aren’t in areas of “oh, we never thought of that!”, but are in very well known areas with known solutions.

I find Go code is obscured with house keeping code that isn’t necessary in better languages.

Re: Go Enums Suck

#120

Earlier quoted context omitted.

Go does not model enums as separate types (like e.g. Pascal), they are essentially just integers like C.

No, Go enums are definitely separate types. Sure, technically there is also an integer (or some other base representation) hidden in there somewhere, but that's what an enumeration is. Without that you don't have an enum.

Creating new types wrapping int is not really the same thing. It's not a closed set. Presumably one could define additional overlapping constants with the same integer type elsewhere?
Post reply on HN