Live data from Hacker News

Compile-time safety for enumerations in Go

vladimir.varank.in

101–110 of 116 posts

Re: Compile-time safety for enumerations in Go

#101
post #74

Earlier quoted context omitted.

It's stuff that just creeps in. Enum values can come from outside (json, anything non-literal). Now you have to do validation, because the bad values parse and for sure exist at some stage in your program. It's not a bogeyman.

Accidental zero value enums are a constant plague as far as I've seen. Almost any defense is worth it.

zero-values are the root of all go problems. Lack of sum/union/algebraic types are the root if zero-values.

Re: Compile-time safety for enumerations in Go

#102
post #19

Unfortunately not. func main() { c := color.Red cptr := (*string)(&c) *cptr = "orange" PrintColor(c) // successfully compiles, and prints "orange" }

It's the game of the mouse and the cat :-D We can change the package color like this :

  package color

  type Color interface {
    void()
  }

  type color struct {
    v string
  }

  func (c color) void() {}
  func (c color) String() string {
    return c.v
  }

  var (
    Red   color = color{"red"}
    Green color = color{"green"}
    Blue  color = color{"blue"}
  )

Re: Compile-time safety for enumerations in Go

#103
post #2

I 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 hope Go will eventually get sum types but I hope they're better than Rust's where each variant is its own type.

> Rust's where each variant is its own type.

Is this... right? You can't use enum variants as types in function signatures, variable declarations, etc.

Re: Compile-time safety for enumerations in Go

#104
post #46

I would be interested to read bug reports from people who thought they had a complete enumeration but learned in production that their enumeration was incomplete. I've never seen it myself.

An easy way to get that is when you use a third-party library, update that to get some new feature, and get a new enum value for free, say because the html parser library started supporting a new node type or added a new error type (the latter will be rare in go because of its lack of sum types). Ideally, of course, the release notes of the library would spell out the issue, and you’d read them, but even then, making…

One difficulty with this is, adding a new enum value should therefore be semver-major.

Re: Compile-time safety for enumerations in Go

#105
post #51
post #45

Earlier quoted context omitted.

I think by insisting to view it only as a boolean thing is very limiting. By that measure, are the type safety hints of Python not really giving any type safety? Just give up and go home, as it were? :D I'm sympathetic to the points, I think. But I also don't have a problem with someone pushing for some type safety as long as you avoid actively trying to go against it.

> By that measure, are the type safety hints of Python not really giving any type safety? If we're talking compile-time, then: yes, absolutely! Type hinting doesn't provide type safety, because type safety isn't a spectrum.

To me it's pretty clear that safety is a spectrum (e.g. we give cars safety ratings), and therefore so is type safety.

Is "type safety" something you saw defined in a PL book or something, which has a more rigid definition to you?

Re: Compile-time safety for enumerations in Go

#106

Earlier quoted context omitted.

I hope Go will eventually get sum types but I hope they're better than Rust's where each variant is its own type.

How is this mess better than Rust's enums? A Rust enum + match statement results in really easy to read and clean code.

For a trivial example, let's say I have some message type that has multiple variants with differing fields:

    enum Message {
        Action1(String, Option),
        Action2(String),
    }
Action1 and Action2 are variants not types and I cannot make functions that take an Action1 or an Action2 as a parameter. To get around this people will often make each enum variant just a container for some struct with the same name but that's more verbose and matching becomes slightly uglier. Code like this is fairly common:

    struct Action1(String, Option);

    struct Action2(String);

    enum Message {
        Action1(Action1),
        Action2(Action2),
    }
Ideally I'd like to be able to succinctly say something like:

    type A = B | C
and have A be dependent on B and C but have both B and C be completely independent types.

Re: Compile-time safety for enumerations in Go

#107

Earlier quoted context omitted.

How is this mess better than Rust's enums? A Rust enum + match statement results in really easy to read and clean code.

For a trivial example, let's say I have some message type that has multiple variants with differing fields: enum Message { Action1(String, Option ), Action2(String), } Action1 and Action2 are variants not types and I cannot make functions that take an Action1 or an Action2 as a parameter. To get around this people will often make each enum variant just a container for some struct with the same name but that's more ve…

That is a pretty compelling point... I ran into this less than an hour ago and was slightly frustrated.

Though, I still like the flexibility of adding additional fields to `Action1`. In golang I end up with fields that are conditionally populated based on the state of an Enum which is less than ideal and leads to lots of error checking (though this is relatively rare).

It doesn't have to be one or the other though. A bit more polishing on the Rust-style enums (perhaps in a different language) could lead to pretty ergonomic code.

Re: Compile-time safety for enumerations in Go

#108
post #16

Earlier quoted context omitted.

> I still feel as though languages without sum types are missing an important data and state modelling tool. That's because they are. jerf subtly shifts the point to one they can criticise, but it does not change the basic fact that sum types are a critical tool which is just... missing. There's probably no tool which can't be misused, even the humble boolean, that's not an issue with the tool, and pointing that out…

Where I'd disagree is that they are a tool, not a critical tool, and they aren't missing from Go, they are simply not the preferred choice. You can cover 75% of the use cases with this approach. It is not 100% of the use cases. But there isn't a language where you can cover 100% of the use cases with 100% effectiveness, which is why we don't have and never will have The One True Language. Moreover, Go seems to attrac…

[deleted]

Re: Compile-time safety for enumerations in Go

#109
post #8

I sometimes do this but idk if I would consider it 'elegant' The 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.

>I just wish go had proper sum types. It's by far my favorite feature of Swift. Enums + Payloads + switches are incredibly simple yet so effective. You can make a simple state object, isolate it with an actor, then stream it anywhere with Combine (or now Observability). You'll get full compiler safety too, forcing any new state to be handled everywhere. You can even stack that with _generic_ payloads that conform to…

Love this. Not only is it my favorite feature of swift, but I often say swift enums are my favorite feature of any programming language. They are just so elegant and powerful

Re: Compile-time safety for enumerations in Go

#110
post #7
post #4

Earlier quoted context omitted.

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…

I think the answer to your "back and forth" is probably laid out in: https://jerf.org/iri/post/2960/ 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. Som…

I guess what I don’t understand about this is sum types represent a state that is so ubiquitous in our lives that it’s hard for me to go a day without seeing one. It’s simply the state of something either is this or that or that. It would be like a language without records. It’s missing a part of reality that shows up all the time
Post reply on HN