Skip to content

Commit ffefcd3

Browse files
committed
spec: introduce notion of strict comparability
- Rephrase the notion of "comparability" from a property of values (operands) to a property of types and adjust dependent prose. - Introduce the notion of "strict comparability". - Fix the definitions of comparability for type interfaces and type parameters. - Define the predeclared identifier "comparable" as stricly comparable. These changes address existing problems in the spec as outlined in the section on "Related spec issues" in issue #56548. For #56548. Change-Id: Ibc8c2f36d92857a5134eadc18358624803d3dd21 Reviewed-on: https://go-review.googlesource.com/c/go/+/457095 Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> TryBot-Bypass: Robert Griesemer <[email protected]> Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent cb07765 commit ffefcd3

File tree

1 file changed

+57
-27
lines changed

1 file changed

+57
-27
lines changed

doc/go_spec.html

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--{
22
"Title": "The Go Programming Language Specification",
3-
"Subtitle": "Version of November 21, 2022",
3+
"Subtitle": "Version of December 14, 2022",
44
"Path": "/ref/spec"
55
}-->
66

@@ -2684,18 +2684,17 @@ <h4 id="Type_constraints">Type constraints</h4>
26842684
The <a href="#Predeclared_identifiers">predeclared</a>
26852685
<a href="#Interface_types">interface type</a> <code>comparable</code>
26862686
denotes the set of all non-interface types that are
2687-
<a href="#Comparison_operators">comparable</a>. Specifically,
2687+
<a href="#Comparison_operators">strictly comparable</a>. Specifically,
26882688
a type <code>T</code> implements <code>comparable</code> if:
26892689
</p>
26902690

26912691
<ul>
26922692
<li>
2693-
<code>T</code> is not an interface type and <code>T</code> supports the operations
2694-
<code>==</code> and <code>!=</code>; or
2693+
<code>T</code> is not an interface type and <code>T</code> is strictly comparable; or
26952694
</li>
26962695
<li>
26972696
<code>T</code> is an interface type and each type in <code>T</code>'s
2698-
<a href="#Interface_types">type set</a> implements <code>comparable</code>.
2697+
<a href="#Interface_types">type set</a> is strictly comparable.
26992698
</li>
27002699
</ul>
27012700

@@ -2707,12 +2706,13 @@ <h4 id="Type_constraints">Type constraints</h4>
27072706
</p>
27082707

27092708
<pre>
2710-
int // implements comparable
2709+
int // implements comparable (int is strictly comparable)
27112710
[]byte // does not implement comparable (slices cannot be compared)
27122711
interface{} // does not implement comparable (see above)
2713-
interface{ ~int | ~string } // type parameter only: implements comparable
2714-
interface{ comparable } // type parameter only: implements comparable
2715-
interface{ ~int | ~[]byte } // type parameter only: does not implement comparable (not all types in the type set are comparable)
2712+
interface{ ~int | ~string } // type parameter only: implements comparable (int, string types are stricly comparable)
2713+
interface{ comparable } // type parameter only: implements comparable (comparable implements itself)
2714+
interface{ ~int | ~[]byte } // type parameter only: does not implement comparable (slices are not comparable)
2715+
interface{ ~struct{ any } } // type parameter only: does not implement comparable (field any is not strictly comparable)
27162716
</pre>
27172717

27182718
<p>
@@ -5019,93 +5019,99 @@ <h3 id="Comparison_operators">Comparison operators</h3>
50195019
</p>
50205020
<p>
50215021
The equality operators <code>==</code> and <code>!=</code> apply
5022-
to operands that are <i>comparable</i>.
5022+
to operands of <i>comparable</i> types.
50235023
The ordering operators <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, and <code>&gt;=</code>
5024-
apply to operands that are <i>ordered</i>.
5024+
apply to operands of <i>ordered</i> types.
50255025
These terms and the result of the comparisons are defined as follows:
50265026
</p>
50275027

50285028
<ul>
50295029
<li>
5030-
Boolean values are comparable.
5030+
Boolean types are comparable.
50315031
Two boolean values are equal if they are either both
50325032
<code>true</code> or both <code>false</code>.
50335033
</li>
50345034

50355035
<li>
5036-
Integer values are comparable and ordered, in the usual way.
5036+
Integer types are comparable and ordered.
5037+
Two integer values are compared in the usual way.
50375038
</li>
50385039

50395040
<li>
5040-
Floating-point values are comparable and ordered,
5041-
as defined by the IEEE-754 standard.
5041+
Floating-point types are comparable and ordered.
5042+
Two floating-point values are compared as defined by the IEEE-754 standard.
50425043
</li>
50435044

50445045
<li>
5045-
Complex values are comparable.
5046+
Complex types are comparable.
50465047
Two complex values <code>u</code> and <code>v</code> are
50475048
equal if both <code>real(u) == real(v)</code> and
50485049
<code>imag(u) == imag(v)</code>.
50495050
</li>
50505051

50515052
<li>
5052-
String values are comparable and ordered, lexically byte-wise.
5053+
String types are comparable and ordered.
5054+
Two string values are compared lexically byte-wise.
50535055
</li>
50545056

50555057
<li>
5056-
Pointer values are comparable.
5058+
Pointer types are comparable.
50575059
Two pointer values are equal if they point to the same variable or if both have value <code>nil</code>.
50585060
Pointers to distinct <a href="#Size_and_alignment_guarantees">zero-size</a> variables may or may not be equal.
50595061
</li>
50605062

50615063
<li>
5062-
Channel values are comparable.
5064+
Channel types are comparable.
50635065
Two channel values are equal if they were created by the same call to
50645066
<a href="#Making_slices_maps_and_channels"><code>make</code></a>
50655067
or if both have value <code>nil</code>.
50665068
</li>
50675069

50685070
<li>
5069-
Interface values are comparable.
5071+
Interface types that are not type parameters are comparable.
50705072
Two interface values are equal if they have <a href="#Type_identity">identical</a> dynamic types
50715073
and equal dynamic values or if both have value <code>nil</code>.
50725074
</li>
50735075

50745076
<li>
50755077
A value <code>x</code> of non-interface type <code>X</code> and
5076-
a value <code>t</code> of interface type <code>T</code> are comparable when values
5077-
of type <code>X</code> are comparable and
5078+
a value <code>t</code> of interface type <code>T</code> can be compared
5079+
if type <code>X</code> is comparable and
50785080
<code>X</code> <a href="#Implementing_an_interface">implements</a> <code>T</code>.
50795081
They are equal if <code>t</code>'s dynamic type is identical to <code>X</code>
50805082
and <code>t</code>'s dynamic value is equal to <code>x</code>.
50815083
</li>
50825084

50835085
<li>
5084-
Struct values are comparable if all their fields are comparable.
5086+
Struct types are comparable if all their field types are comparable.
50855087
Two struct values are equal if their corresponding
50865088
non-<a href="#Blank_identifier">blank</a> field values are equal.
50875089
The fields are compared in source order, and comparison stops as
50885090
soon as two field values differ (or all fields have been compared).
50895091
</li>
50905092

50915093
<li>
5092-
Array values are comparable if values of the array element type are comparable.
5094+
Array types are comparable if their array element types are comparable.
50935095
Two array values are equal if their corresponding element values are equal.
50945096
The elements are compared in ascending index order, and comparison stops
50955097
as soon as two element values differ (or all elements have been compared).
50965098
</li>
5099+
5100+
<li>
5101+
Type parameters are comparable if they are strictly comparable (see below).
5102+
</li>
50975103
</ul>
50985104

50995105
<p>
51005106
A comparison of two interface values with identical dynamic types
5101-
causes a <a href="#Run_time_panics">run-time panic</a> if values
5102-
of that type are not comparable. This behavior applies not only to direct interface
5107+
causes a <a href="#Run_time_panics">run-time panic</a> if that type
5108+
is not comparable. This behavior applies not only to direct interface
51035109
value comparisons but also when comparing arrays of interface values
51045110
or structs with interface-valued fields.
51055111
</p>
51065112

51075113
<p>
5108-
Slice, map, and function values are not comparable.
5114+
Slice, map, and function types are not comparable.
51095115
However, as a special case, a slice, map, or function value may
51105116
be compared to the predeclared identifier <code>nil</code>.
51115117
Comparison of pointer, channel, and interface values to <code>nil</code>
@@ -5126,6 +5132,30 @@ <h3 id="Comparison_operators">Comparison operators</h3>
51265132
)
51275133
</pre>
51285134

5135+
<p>
5136+
A type is <i>strictly comparable</i> if it is comparable and not an interface
5137+
type nor composed of interface types.
5138+
Specifically:
5139+
</p>
5140+
5141+
<ul>
5142+
<li>
5143+
Boolean, numeric, string, pointer, and channel types are strictly comparable.
5144+
</li>
5145+
5146+
<li>
5147+
Struct types are strictly comparable if all their field types are strictly comparable.
5148+
</li>
5149+
5150+
<li>
5151+
Array types are strictly comparable if their array element types are strictly comparable.
5152+
</li>
5153+
5154+
<li>
5155+
Type parameters are strictly comparable if all types in their type set are strictly comparable.
5156+
</li>
5157+
</ul>
5158+
51295159
<h3 id="Logical_operators">Logical operators</h3>
51305160

51315161
<p>

0 commit comments

Comments
 (0)