Proposal Details
Background
From https://github.com/golang/go/issues/56773:
Generics introduced the constraint comparable which denotes the set of all types which are strictly comparable. An API may define an exported type T which may be strictly comparable (see https://github.com/golang/go/issues/56548 for terminology) and such a type T may successfully be used as type argument for comparable type parameters elsewhere.
It's possible to change T without visible API change so that it's not strictly comparable anymore.
Whether an exported type is strictly comparable should be considered a part of its API. As such, it would be useful if this property were exposed through go/types
.
Determining whether a type is spec-comparable is exposed via types.Comparable
:
https://github.com/golang/go/blob/b199d9766a8957c686ece568483586f08fc9a8b4/src/go/types/predicates.go#L155-L158
In the call comparableType(T, true, nil, nil)
, the boolean parameter indicates spec-comparability (true
). Setting this parameter to false
indicates strict comparability.
Proposal
Add the following function to go/types
:
// StrictlyComparable reports whether values of type T are strictly comparable
// (https://go.dev/ref/spec#Comparison_operators).
func StrictlyComparable(T Type) bool {
return comparableType(T, false, nil, nil)
}
Comment From: gabyhelp
Related Issues
- cmd/api: api checker should check types for change in comparability #56773
- proposal: spec: add comparable w/o interfaces #49587 (closed)
- proposal: spec: allow interface types to instantiate `comparable` type parameters #52509 (closed)
- proposal: type parameters are comparable unless they exclude comparable types #52614 (closed)
- proposal: spec: permit values to have type "comparable" #51338 (closed)
- proposal: spec: add new constraint kind satisfied by types that support == (including interface types) #52531 (closed)
- proposal: spec: permit non-interface types that support == to satisfy the comparable constraint #52474 (closed)
Related Code Changes
- spec: introduce notion of strict comparability
- spec: add section on comparable constraint
- [dev.go2go] go/types: prevent comparable interface from being used outside constraints
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: ianlancetaylor
CC @griesemer @adonovan @findleyr
Comment From: kwjw
CC @jba
apidiff
could make use of a function like StrictlyComparable
. If a previously spec-comparable struct is changed to no longer be comparable, apidiff
reports this as an incompatible change. There should be a similar rule for maintaining strict comparability.
Comment From: findleyr
I agree that we should add this. In principle, we should support any type predicate that appears in the spec.
Comment From: kwjw
@adonovan
Any interest in this proposal?
It's a trivial addition that exposes a meaningful type predicate and could plug a small hole in checking for API compatibility.
OTOH it doesn't seem like there's any rush to tackle #56773 (probably the main beneficiary of this change).
Comment From: atdiar
I've had new thoughts about the necessity of strictly comparable but didn't get around to rediscuss it properly with @griesemer or @ianlancetaylor Basically that would bring generics closer to the semantics of non-generic go code which doesn't actually rely on the notion of strict comparability. That could fix some of what I think are currently still some actual bugs, for example in #57486
With the new change to core types, that could even make comparable redundant and simplify the spec.