Live data from Hacker News

What I'd like to see in Go 2.0

sethvargo.com

171–180 of 223 posts

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

#171

Earlier quoted context omitted.

Exhaustive switch seems likely to be backward incompatible if done well. What you want here is something akin to Rust's match behaviour on enumerated types. If your alternatives aren't exhaustive, it doesn't compile. Now, Rust is doing that because match is an expression . Your day matching expression needs a value if this is a Thursday, so not handling Thursday in your day matching expression is nonsense - even thou…

> Exhaustive switch seems This would only make sense on an enum type, which would be a completely new thing, so it can be introduced without breaking backward compatibility. Constants and switch on non-enum values would stay, because they are useful independent of enum types.

Also makes sense on numbers and other patterns where you can logically enforce exhaustiveness.

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

#172

Earlier quoted context omitted.

could be interesting, however I'd hope for something more visually distinctive that val/var as it took about 2-3 reads for me notice what was even the diff between L2 and L3.

Fair point. "value" and "var" then, perhaps?

perhaps, the real details would get hammered out in a proposal.

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

#173

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…

Just adding to the discussion:

I find this comment from Griesemer [0] on one of the github issues for enums in Golang quite insightful:

>> [...] all the proposals on enums I've seen so far, including this one, mix way too many things together in my mind. [...] Instead, I suggest that we try to address these (the enum) properties individually. If we had a mechanism in the language for immutable values (a big "if"), and a mechanism to concisely define new values (more on that below), than an "enum" is simply a mechanism to lump together a list of values of a given type such that the compiler can do compile-time validation.

Like with generics, I like the team's approach of taking features seriously, not adding them just because other languages have them, but actually trying to figure out a way for them to work in Go, as cleanly as possible. I think computer science, as a field, benefits from this approach.

And I also dislike many things from Go, and I want "enums" badly too, but that's for another comment.

[0] https://github.com/golang/go/issues/28987#issuecomment-49679...

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

#174
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…

The fix is pretty simple, just declare err ahead of time: func doThing() string { result := "OK" var err error if result, err = somethingelse(); err != nil { return "ERROR" } return result }

The issue is now you have a potential nil value hanging around in the code with no real reason for its existence. Three refactors and some moving around later and you manage to hit a runtime panic in production.

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

#175

I would add: an extended standard library for "common stuff". I don't want to import a third-party library nor write my own "utils.go" to do: func contains(s []int, e int) bool { for _, a := range s { if a == e { return true } } return false }

soon-ish https://cs.opensource.google/go/x/exp/+/master:slices/slices...

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

#176

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…

Or even better, proper sum types. They're a superset of enums anyway. https://github.com/BurntSushi/go-sumtype is great, but a bit unwieldy. Language support would be much better.

Proper compile time sum types would be great. I find myself reimplementing sum types at runtime far too often, especially when it comes to parsing JSON. My go to is a function with a signature along the lines of the reflect packages dynamic select:

func UnmarshalOneOf(data []byte, args []interface{}) (index int, err error)

Which I use like this:

variants := []interface{}{ &T1{}, &T2{}}

i, err := UnmarshalOneOf(data, variants)

// …

return variants[i]

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

#177

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…

IME the problem is the default behavior. Rust, Java, et al have that same default behavior of defaulting to closed enums, and you have to opt-in to open enums. Whether that's adding a type attribute in Rust or implementing special code in Java to handle the case. This is a footgun for distributed systems. If you don't get it wrong, then clients writing their own client-side software will get it wrong.

I'm not disparaging closed enums, they are very useful in certain contexts, but they make it really easy to do the wrong thing when reading data off the wire. Given Go is focused on this exact domain (distributed systems), I am glad the language doesn't have them.

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

#178
What I would like to see:

- Enun Types

- A special operator to cut down on `if err != nil { return err }` and just return at that point.

- Named arguments, and optional params with defaults

- Default values on structs

- ...macros? We already have `go generate ./...`

( edit: Removed unformatted source code )

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

#179

Earlier quoted context omitted.

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?

Oooor the language can have proper type-safe enumerated types of some sort, and if you're in a domain where that's an issue you don't use them.

Go is focused on the distributed systems domain though. It's fine, even desirable, to have languages focused on particular domains, that make design decisions based on the constraints of the domain. In this domain, closed enums are footguns with costly consequences if you get it wrong.

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

#180
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?

I would be okay with an open-by-default enum type. (I think...I'm not sure I've ever encountered a language with open-by-default enums.)

I'm still not sure if it's worth it, it's idiomatic Go to "fall-through" if-branches for default cases, which is the same when checking quasi-enums. The symmetry is nice and makes it very easy to read. But I could be convinced.

Post reply on HN