Compile-time safety for enumerations in Go
vladimir.varank.in
Compile-time safety for enumerations in Go
1–10 of 116 posts
Re: Compile-time safety for enumerations in Go
#2What I really wish Go had was sum types, Rust style. That'd cover enumerations and more.
Re: Compile-time safety for enumerations in Go
#3Proper enums would be elegant, not this.
Re: Compile-time safety for enumerations in Go
#4I dunno if I'd consider having a dummy method on an interface as "elegant", but it does work. A trade-off of keeping the language very simple, for sure. What I really wish Go had was sum types, Rust style. That'd cover enumerations and more.
Pattern matching and exhaustive checks are massive benefits of them though. I guess I'm just oddly conflicted here.
I do think that long term, sum types are going to become more prevalent. I'm excited to see it, I'm just interested in how that adoption occurs in existing languages without them.
Re: Compile-time safety for enumerations in Go
#5I dunno if I'd consider having a dummy method on an interface as "elegant", but it does work. A trade-off of keeping the language very simple, for sure. What I really wish Go had was sum types, Rust style. That'd cover enumerations and more.
I go back and forth on this. On one hand, I _love_ Rust/ML style sum types. They're such a fantastic feature. On the other hand, I wonder how much use they'd get in a language like Go. If it's introduced, would it radically change the way some problems get solved? Is it that different than an traditional enum (which Go also skirts around)? Pattern matching and exhaustive checks are massive benefits of them though. I…
Re: Compile-time safety for enumerations in Go
#6I dunno if I'd consider having a dummy method on an interface as "elegant", but it does work. A trade-off of keeping the language very simple, for sure. What I really wish Go had was sum types, Rust style. That'd cover enumerations and more.
type Vehicle interface {
isVehicle()
}
type Car struct {}
func (c Car) isVehicle() {}
type Van struct {}
func (v Van) isVehicle() {}
func VehicleType(vehicle Vehicle) {
switch v := vehicle.(type) {
case Car:
fmt.Println("car")
case Van:
fmt.Println("van")
default:
fmt.Println("unknown vehicle")
}
This covers most, but not all, of the bases, in that you don't get exhaustiveness checking at compile time, unless you adjoin a linter to your compile process: https://github.com/BurntSushi/go-sumtypeRe: Compile-time safety for enumerations in Go
#7I dunno if I'd consider having a dummy method on an interface as "elegant", but it does work. A trade-off of keeping the language very simple, for sure. What I really wish Go had was sum types, Rust style. That'd cover enumerations and more.
I go back and forth on this. On one hand, I _love_ Rust/ML style sum types. They're such a fantastic feature. On the other hand, I wonder how much use they'd get in a language like Go. If it's introduced, would it radically change the way some problems get solved? Is it that different than an traditional enum (which Go also skirts around)? Pattern matching and exhaustive checks are massive benefits of them though. I…
Sum types are useful, even very useful in the right place, but I do think there's a lot of people who use them a couple of times, probably in one of those "right places" and then mistakenly label them in their mind as "better". Just, universally, Platonically "better". They aren't in fact "better"; they're a tool. Sometimes they're the right tool for the job, but much, much more often, they're just a tool that works, and so do several other tools. People who get too excited about sum types need to be sure they square their understanding of how useful they are with the fact that the vast majority of programs are written without them.
Re: Compile-time safety for enumerations in Go
#8The other 'gotcha' is that in switch statements the compiler can't tell whether you enumerated on all your cases as there is no true enum type so it's not uncommon to have a catch all default case that either returns an error or panics and hope you can catch it during tests if you missed a case.
I just wish go had proper sum types.
Re: Compile-time safety for enumerations in Go
#9Re: Compile-time safety for enumerations in Go
#10> Go’s type system allows preventing both issues in a rather elegant way. Proper enums would be elegant, not this.
type Foo interface { A | B | C }
and the interface type is the union of those type-sets. Such interfaces can not currently be used outside of type constraints, but if that is relaxed, and type switches are updated to support and enforce exhaustive matching (and understand such sealed / nominative interfaces), you've got all the bits you need.You'd need to newtype variants to add payloads of similar underlying type e.g. `int | int`, but that's not a huge imposition, and the variants being types themselves is often convenient so it's a 50:50 tradeoff compared to classic sum type (where constructors disambiguate all variants but are not themselves types).