Live data from Hacker News

What I'd like to see in Go 2.0

sethvargo.com

161–170 of 223 posts

Re: What I'd like to see in Go 2.0

#161
post #19

Earlier quoted context omitted.

Personally I’ve run into more problems with strict enum types in distributed systems in a team setting, than I have with Go’s lack of them. In that setting, strict enums are usually over-strict and eventually you back yourself into a corner in terms of being able to roll out new enum values. When there’s no clear winner in terms of tradeoffs, I prefer to leave it out of the language like Go has done.

What problems did an enum cause you, and how was the enum responsible for the problem?

This is a known issue with Rust, for example. I have an enum with variants A and B. Somebody writes an exhaustive switch (match statement) that handles A and B with no default case. I add a variant C. Their code breaks because they don’t handle C. Adding an enum variant was a breaking change.

In Rust, the answer is #[non_exhaustive], which forces consumers to always add a default case. It’s not a huge deal, just a known issue with a well-understood solution.

Re: What I'd like to see in Go 2.0

#162
I want golang to stay as minimal as possible. I think of go as 2020s version of C. If you want all the madness of templating, reflection and (arguably) needless features can some privileged PhD student out there please make 2020s C++… go++?

Re: What I'd like to see in Go 2.0

#163

I'd add one more to this list: proper enum types. We use enums heavily to force devs who use our code into good choices, but the options are currently: 1) Use int-type enums with iota: no human-readable error values, no compile-time guard against illegal enum values, no exhaustive `switch`, and no autogenerated ValidEnumValues for validation at runtime (we instead need to create ValidEnumValues and remember to update…

I don't think you would need a 2.0 (backward-incompatible language change) for any of this.

Sum types overlap a lot with what interfaces over. So enhancing the language with proper sum-types would benefit from enhancing interfaces and switch statements.

However, zero values throw a wrench into this. The zero value of an interface is nil, so enhancing interfaces would require you to address what happens with an uninitialized variable. One of the current proposals suggests that nil continue as the zero value.

They could introduce a totally different type, like a sealed interface, which doesn't require a zero value, but that distinguishes between different types of interfaces, and I'm not sure how that'll be received.

Re: What I'd like to see in Go 2.0

#164
Mine would be a much larger collections library. Having come to go from Java and finding that the standard go library has no trees, no stack, no skip list, etc. was quite a surprise. Possibly the advent of generics will stimulate development of a more robust standard collections library.

Re: What I'd like to see in Go 2.0

#166
post #90

Earlier quoted context omitted.

> We use enums heavily to force devs who use our code into good choices 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’…

Every time I see discussion about go and enums there are people who are referencing these mythical C-like enums that had never existed. It's some sort of constructed memory. And I'm sure there are languages that do enums "properly", but it's always C/C++ that is referenced.

Ada does them well. They have attributes that allow for converting to and from integers and strings [1], and case statements have to be exhaustive or use a default "others" clause.

[1] https://en.wikibooks.org/wiki/Ada_Programming/Types/Enumerat...

Re: What I'd like to see in Go 2.0

#167

Earlier quoted context omitted.

What problems did an enum cause you, and how was the enum responsible for the problem?

This is a known issue with Rust, for example. I have an enum with variants A and B. Somebody writes an exhaustive switch (match statement) that handles A and B with no default case. I add a variant C. Their code breaks because they don’t handle C. Adding an enum variant was a breaking change. In Rust, the answer is #[non_exhaustive], which forces consumers to always add a default case. It’s not a huge deal, just a kn…

I guess I don't quite get this. What I'm seeing here is that a non obvious breaking change is being turned into an obvious one.

If something is handling A and B, but you add C, the code probably needs to make sure it's handling C correctly.

I use Java in my dayjob and the behavior you've outlined is how I always code things, but it's manual and doesn't happen at compile time: I provide default that throws a runtime exception.

Re: What I'd like to see in Go 2.0

#168
post #19

Earlier quoted context omitted.

Personally I’ve run into more problems with strict enum types in distributed systems in a team setting, than I have with Go’s lack of them. In that setting, strict enums are usually over-strict and eventually you back yourself into a corner in terms of being able to roll out new enum values. When there’s no clear winner in terms of tradeoffs, I prefer to leave it out of the language like Go has done.

That's a fair concern: if everything is strict, then there's no option to incrementally roll out a new value. Maybe a proper enum type could always have an `Unknown` value, which would allow for the leniency while still forcing the use to think about (and handle) it at compile time?

Rust supports #[non_exhaustive] attributes, forcing users to cover the generic/wildcard case even though you have already covered all existing ones. Although, I rather do versioning and a breaking change if possible. Put it on the parsing/interop level rather than deep in the code during runtime because it is very likely that your code is not correct without handling the extra case either way.

https://doc.rust-lang.org/reference/attributes/type_system.h...

Re: What I'd like to see in Go 2.0

#169

Earlier quoted context omitted.

> strict enums are usually over-strict and eventually you back yourself into a corner in terms of being able to roll out new enum values. Yes, they are poison for the evolution of a public API.

Swift solved this problems with [non-exhaustive enums]( https://github.com/apple/swift-evolution/blob/main/proposals... ).

Is it solved? How do you decide which enums are final and which ones need to be non-exhaustive to allow evolving the code?

I think that Go's decision stems from protocol buffers as they allow to push new values through old binaries, which is a must once you grow enough.

https://developers.google.com/protocol-buffers/docs/proto3#e...

Re: What I'd like to see in Go 2.0

#170
post #20

Everyone has their own gripes. Modules are what cause me the most pain in Go - especially where they're in github and I need to fork them and now change all the code that references them. I don't know if the problems are even tractable because the way it all works is so incredibly complicated and any change would break a lot. I would like to remove all the "magic" that's built-in for specific SCMS/repository hosting…

Easily fixed using lexical scopes: func doThing() string { result := "OK" { var err error if result, err = somethingElse(); err != nil { return "ERROR" } } return result } `err` is introduced in the lexical scope, `result` isn't so it still refers to the string from the surrounding scope. `err` does not pollute the surrounding scope. You can also try the complete version here: https://go.dev/play/p/kDEB11YdvSs

In my experience this isn’t idiomatic Go and would definitely turn heads in a code review. But in such a small function, it’s fine to just not worry about the lifetime of your variables (and in bigger functions you can often decompose into smaller functions).
Post reply on HN