5 ms·
The type sets proposal for Go has already been accepted as a clarification to the generics proposal [0]: type SignedInteger interface { ~int | ~int
by ibraheemdev 5y ago
The type sets proposal for Go has already been accepted as a clarification to the generics proposal [0]:
type SignedInteger interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
Interfaces that contain type sets are only allowed to be used in generic constraints. However, a future extension might permit the use of type sets in regular interface types:
> We have proposed that constraints can embed some additional elements. With this proposal, any interface type that embeds anything other than an interface type can only be used as a constraint or as an embedded element in another constraint. A natural next step would be to permit using interface types that embed any type, or that embed these new elements, as an ordinary type, not just as a constraint.
> We are not proposing that today. But the rules for type sets and methods set above describe how they would behave.
Any type that is an element of the type set could be assigned to such an interface type. A value of such an interface type would permit calling any member of the corresponding method set.
> This would permit a version of what other languages call sum types or union types. It would be a Go interface type to which only specific types could be assigned. Such an interface type could still take the value nil, of course, so it would not be quite the same as a typical sum type.
> In any case, this is something to consider in a future proposal, not this one.
This along with exhaustive type switches would bring Go something close to the sum types of Rust and Swift.
[0]: https://github.com/golang/go/issues/45346 https://github.com/golang/go/issues/45346
- pcwalton 5y agoThat looks like a great feature to add to Go! It seems to make the original article (which is from 2018) obsolete.
- saghm 5y agoOne difference between this proposal and Rust enums (i.e. tagged unions) is that enums let you use the same type more than once with a different tag. Obviously Go doesn't have generics yet, but something like `Result<String, String>` doesn't seem like it would be straightforward as a non-generic type either with a type set, since you don't have any way of differentiating between which "type" of string you might have. I _think_ this might be possible with a typeset by defining a newtype for one or both of the string types, but I haven't used Go in long enough that I don't remember if newtypes will implicitly convert to the type they wrap or not.
- masklinn 5y agoWith this proposal the variants are simply types themselves, so you'd have a struct Ok[T] and Err [T], and thus Result<T, E> would be something like interface Result[T, E] { for Ok[T], Err[E] } And there’s no issue with having T=string and E=string.
- cube2222 5y agoThey don't implicitly convert (though you can still use literals to create them). So yes, specifying Ok and Error string types should hypothetically work for this.
- pcwalton 5y agoYeah, the standard solution is to create a newtype for each such variant. I believe this is the preferred idiom in languages like TypeScript that have union types but not discriminated union types.
- brundolf 5y agoTypescript does have discriminated union types, you just have to use objects with a discriminating property which is a bit less ergonomic than the way those work in other languages. It's done this way to preserve TypeScript's goal of having little to no impact on runtime behavior
- ibraheemdev 5y agoI believe this would work with type sets: type Result[T any, E any] interface { T | E }
- lmm 5y agoIf T=int32 and E=int32, does this behave like int32 | int32? If so, how can you tell which it is? (Presumably you have generic code that needs to know whether this case is T or E). If not, that's pretty surprising.
- 5y ago
- adtac 5y agoWhat's the best way to read about all the new accepted grammar developments in Go in the last year or two?
- benhoyt 5y agoThe Go grammar/language changes very slowly -- most of the improvements are in the tooling and libraries, so there isn't much. But the best way is the release notes. For the last two years (four versions): https://golang.org/doc/go1.17 https://golang.org/doc/go1.17: three very minor changes for array pointers and unsafe https://golang.org/doc/go1.16 https://golang.org/doc/go1.16: no language changes https://golang.org/doc/go1.15 https://golang.org/doc/go1.15: no language changes https://golang.org/doc/go1.14 https://golang.org/doc/go1.14: minor change to allow "overlapping interfaces" Of course, in 1.18 -- coming out in about three months -- there's the huge change to add generics (type parameters). The best way to read about that is in the type parameters proposal here: https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md https://go.googlesource.com/proposal/+/refs/heads/master/des... Go 1.18 will also add built-in fuzzing support, but again, that's a tooling/library change, not a grammar/language one.