Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: Go 2: range types #30428

Open
beoran opened this issue Feb 27, 2019 · 3 comments

Comments

@beoran
Copy link

commented Feb 27, 2019

Background

Go currently does not support enumerated types nor ranged types. The former is a widely requested feature, but can be considered a special case of the latter.

Enumerated types are widely availabe in many languages, Go is one of the few languages wich does not have this feature. Ranged types appear in several Wirth languages such as Pascal, Ada and Module-3. Both enumerated and ranged types are useful in application where constants and variables may only assume certain values or must be guaranteed to be in certain ranges

I wrote this proposal as a result of the discussion in #29649 and #28987, and now I'd like to make it a separate issue as one of the competing proposals for adding an "enum" like type to Go.

Abstract

I propose these related changes to the type system in Go:

  • Add bounded range types with upper and lower bounds as in type Range range float64 [-5.0:5.0]
  • Add enumerated range types that can only have concrete values from a list as in type Enumerated range int {7, 10, -1, 22}
  • Add named range types that have enumerated names with values as in
    type EnumeratedWithNames range int {Foo = 7, Bar = 10, Baz = -1, Quux = 22}. These can be used like this:
    a := EnumeratedWithNames.Foo ; b := EnumeratedWithNames.Quux ;. Or even
    a := range int {Foo = 7, Bar = 10, Baz = -1, Quux = 22}.Foo, for consistency, although that is pretty useless.
  • The user of iota is allowed for named enumerated types like this: type Weekday range int { Monday = iota, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
  • The zero value of a bounded range type is zero if it is in range, otherwise the zero value is its lower bound. For an enumerated range type it is the value of the first member.
  • Extend the range clause to allow enumeration of range types.
  • Extend the built in len() function to allow calling it with range types.
  • Cause all assignments of constants of range type to be checked at compile time.
  • Cause all assignments to variables ranged type to cause a panic if a value out of bounds or not one of the enumerated values is assigned to a variable of a range type. The compiler may, if possible, check the range for variables at compile time in stead of causing a panic at run time, but it will be implementation defined for which variable assignments compile time checking is done or not.
  • Allow all assignments to variables of range type, enumerated, named, and bounded to use the result, ok := form in which case no exception will be raised if a value out of bounds or not one of the enumerated values would be assigned to result, but in stead the assignment does not happen and ok is set to false. Otherwise the assignment happens and ok is set to true.

Rationale

Enumerated types are widely supported in many languages, yet Go still lacks them. Bounded range typoes are implemented in Wirth languages such as Ada because they are useful for critical software where certain values must be guaranteed to always be in a specific range. This proposal adds both these these useful and widely requested types to the Go language, yet keeps these features easy to learn and Go like, and adds these features in a strictly backwards compatible way.

The worked out details of the proposal are here:

https://gist.github.com/beoran/83526ce0c1ff2971a9119d103822533a

@gopherbot gopherbot added this to the Proposal milestone Feb 27, 2019

@gopherbot gopherbot added the Proposal label Feb 27, 2019

@DylanMeeus

This comment has been minimized.

Copy link

commented Feb 27, 2019

Personally, I was not strongly in favour of this idea upon reading your description. Maybe this is because I've not used such types in other languages. I disagree that Go is one of the few languages to not have this feature. It might just seem like one of the few languages to lack this from the subset of languages you've used.

The enum example, is something I can get behind. But that's just because of bias from the subset of languages that I have used that supported such enums.

I feel like this answer by @griesemer stands as a reply to this issue as well, and sums up my feelings about it, so I'll take the liberty to just link to his comment:
#29649 (comment)

@beoran

This comment has been minimized.

Copy link
Author

commented Feb 27, 2019

Well, this is sort of a unifying proposal, but if no one is interested in bounded range types I am willing to drop them from this proposal and only keep the enumerated range types. But first I would like to get more feedback.

@ianlancetaylor ianlancetaylor changed the title proposal: Go 2 Range Types proposal: Go 2: range types Feb 27, 2019

@beoran

This comment has been minimized.

Copy link
Author

commented Mar 14, 2019

It seems that actually bounded range types could also be very useful to control integer overflow. as per the issue #30613 above. So, perhaps it is best they stay part of the proposal, which I already updated since for that purpose.

Of course, it might be an idea to split the proposal up into two, one for bounded range types and one for enumerated range types. If there is any demand for that I will do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.