Live data from Hacker News

Enums in Go

dizzy.zone

41–50 of 57 posts

Re: Enums in Go

#41

I’ve found the enumer [0] library does the job of generating usable helpers without too much pain or any obvious downsides. The ability to generate JSON [un]marshallers is particularly handy. Still, the lack of enums and enum/sum types remains by far my biggest gripe about Go. [0] https://github.com/dmarkham/enumer

The posted article mentions https://github.com/abice/go-enum, which does the same thing, no? It even generates the consts based on a list of values in a comment.

Re: Enums in Go

#42
post #19

I can't take this language seriously. No enums, letter cases defining if something is "public" or "private", generics as an after-thought. To name just a few

To be fair, generics was an after-thought because Go was originally a "small" language used internally at Google, and they needed to ship the language in a working state. Generics was too complicated to handle for the first versions (according to Russ Cox). If you look at Java, generics didn't exist until a few major versions in.

Although I agree it probably should be done quite a bit earlier.

Re: Enums in Go

#43
post #31

Earlier quoted context omitted.

You don't have to add a catch-all arm, you can still explicitly match i.e match value { A => { do_stuff() }, B => { unreachable!("B is not applicable here because ") }, } now when you add C you still have to match it(given the enum is exhaustive).

Yes, I see, I should have mentioned that. Same as above: this solution stops working as soon as you're handling 5 out of 50 cases (or, more realistically, 10 out of 200). Lexical tokens are which always trigger the mentioned problems in my code - often you match against subsets, as there are _way_ too many of them to add them all explicitly.

This is true, but in my experience these are edge cases and explicitly matching everything works well 90% of the time.

Re: Enums in Go

#44
post #31

Earlier quoted context omitted.

You don't have to add a catch-all arm, you can still explicitly match i.e match value { A => { do_stuff() }, B => { unreachable!("B is not applicable here because ") }, } now when you add C you still have to match it(given the enum is exhaustive).

Yes, I see, I should have mentioned that. Same as above: this solution stops working as soon as you're handling 5 out of 50 cases (or, more realistically, 10 out of 200). Lexical tokens are which always trigger the mentioned problems in my code - often you match against subsets, as there are _way_ too many of them to add them all explicitly.

First of all, I think there is a problem with your design if you have 50 or 200 cases. Most of the code I have seen -- in any language -- have no more than 10 cases, rarely 20. Maybe that is the issue to look at first.

Then, this "limitation" is not an argument for not running the exhaustive check. In the vast majority of cases where there are about 5 enum entries and most cases need their own path, they would be explicitly written out (i.e. no _ =>), and this works extremely well. I have had good experience, and I believe other people can attest this.

If you only have 1 case matched and everything else goes in _, later needs to add one case, you just do that, likely in every other language, there is nothing that can help. But what's described above is already a big improvement.

Re: Enums in Go

#45
post #43

Earlier quoted context omitted.

Yes, I see, I should have mentioned that. Same as above: this solution stops working as soon as you're handling 5 out of 50 cases (or, more realistically, 10 out of 200). Lexical tokens are which always trigger the mentioned problems in my code - often you match against subsets, as there are _way_ too many of them to add them all explicitly.

This is true, but in my experience these are edge cases and explicitly matching everything works well 90% of the time.

This is actually the problém. I'd even say that it works like 95% of the time, that's why people (of course, I don't make such silly mistakes ;) aren't used to check where it matters. In reality the policy must be to always (whether there are or aren't working exhaustiveness checks) manually check each and every occurence when adding. Don't get mé wrong, I prefer having exhaustiveness checks, but they make the manually searching a bit less tedious, not alleviate it in total.

Re: Enums in Go

#46
post #44

Earlier quoted context omitted.

Yes, I see, I should have mentioned that. Same as above: this solution stops working as soon as you're handling 5 out of 50 cases (or, more realistically, 10 out of 200). Lexical tokens are which always trigger the mentioned problems in my code - often you match against subsets, as there are _way_ too many of them to add them all explicitly.

First of all, I think there is a problem with your design if you have 50 or 200 cases. Most of the code I have seen -- in any language -- have no more than 10 cases, rarely 20. Maybe that is the issue to look at first. Then, this "limitation" is not an argument for not running the exhaustive check. In the vast majority of cases where there are about 5 enum entries and most cases need their own path, they would be exp…

> this "limitation" is not an argument for not running the exhaustive check.

That's not what I wanted to express. What I wanted to say is, that even when using Haskell, which has all the possibilities to actually handle matches of subsets quite ergonomically, you can't be sure that there isn't at least one čase which isn't caught by the exhaustiveness checker (and sometimes it's just wrong, but then we're not talking about enums). So you always have to check all manually, but the checker makes that easier.

Re: Enums in Go

#47

I’ve found the enumer [0] library does the job of generating usable helpers without too much pain or any obvious downsides. The ability to generate JSON [un]marshallers is particularly handy. Still, the lack of enums and enum/sum types remains by far my biggest gripe about Go. [0] https://github.com/dmarkham/enumer

The posted article mentions https://github.com/abice/go-enum , which does the same thing, no? It even generates the consts based on a list of values in a comment.

Four candidates mentioned so far in the HN comments so far. Here's 45?

https://github.com/search?q=enum+generator+language%3AGo&typ...

https://github.com/search?q=enum+generation+language%3AGo&ty...

Re: Enums in Go

#48
post #27

Enums in Go are not good. Code generation just makes it worse. Both because code generation has a bad smell and because nobody can agree on how to do enums in Go so we just end up with lots of diverging solutions. Go 2 needs to have more usable enums. And while I'm not a big fan of "adding more stuff" to languages, it wouldn't hurt Go to learn a couple of things from Rust.

I can't see why they wouldn't be in a future 1.x release

Re: Enums in Go

#49

I’ve found the enumer [0] library does the job of generating usable helpers without too much pain or any obvious downsides. The ability to generate JSON [un]marshallers is particularly handy. Still, the lack of enums and enum/sum types remains by far my biggest gripe about Go. [0] https://github.com/dmarkham/enumer

The posted article mentions https://github.com/abice/go-enum , which does the same thing, no? It even generates the consts based on a list of values in a comment.

It does indeed seem to be similar, and viable option, with the difference being that the enum values are specified in a comment. You seem enthusiastic about that design decision/feature, howeever I am not sure about it, it scares me a little.

It's absolutely just a hunch and personal preference but I worry that keeping the enum value inputs in comments might not be great for new contributors and in terms of maintaining the codebase over time, so I think I prefer the approach taken by enumer.

Re: Enums in Go

#50
post #26
post #22

Earlier quoted context omitted.

Isn’t that the first thing you would do if you add a new variant?

Only if you remember, which you, or someone else, is bound to not eventually

But you're not adding variants without a reason? You want them to have some effect.

It's hard for me to think of an example where it would make even sense to "having to remember to handle the variant" rather than "handling the desired effect of the variant".

Post reply on HN