Skip to content

Commit 754c8fb

Browse files
authored
PEP 695: Fix/improve syntax & content of Language Survey section (#2725)
1 parent 8207275 commit 754c8fb

File tree

1 file changed

+134
-57
lines changed

1 file changed

+134
-57
lines changed

pep-0695.rst

Lines changed: 134 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -840,19 +840,19 @@ may be useful when considering future extensions to the Python type system.
840840
C++
841841
---
842842

843-
C++ uses angle brackets in combination with keywords "template" and
844-
"typename" to declare type parameters. It uses angle brackets for
843+
C++ uses angle brackets in combination with keywords ``template`` and
844+
``typename`` to declare type parameters. It uses angle brackets for
845845
specialization.
846846

847847
C++20 introduced the notion of generalized constraints, which can act
848848
like protocols in Python. A collection of constraints can be defined in
849-
a named entity called a "concept".
849+
a named entity called a ``concept``.
850850

851851
Variance is not explicitly specified, but constraints can enforce variance.
852852

853-
A default type argument can be specified using the "=" operator.
853+
A default type argument can be specified using the ``=`` operator.
854854

855-
::
855+
.. code-block:: c++
856856

857857
// Generic class
858858
template <typename>
@@ -896,39 +896,44 @@ Java
896896
----
897897

898898
Java uses angle brackets to declare type parameters and for specialization.
899-
The "extends" keyword is used to specify an upper bound.
899+
By default, type parameters are invariant.
900+
The ``extends`` keyword is used to specify an upper bound. The ``super`` keyword
901+
is used to specify a contravariant bound.
900902

901903
Java uses use-site variance. The compiler places limits on which methods and
902904
members can be accessed based on the use of a generic type. Variance is
903905
not specified explicitly.
904906

905907
Java provides no way to specify a default type argument.
906908

907-
::
909+
.. code-block:: java
908910
909911
// Generic class
910912
public class ClassA<T> {
911913
public Container<T> t;
912914
913915
// Generic method
914916
public <S extends Number> void method1(S value) { }
917+
918+
// Use site variance
919+
public void method1(ClassA<? super Integer> value) { }
915920
}
916921
917922
918923
C#
919924
--
920925

921926
C# uses angle brackets to declare type parameters and for specialization.
922-
The "where" keyword and a colon is used to specify the bound for a type
927+
The ``where`` keyword and a colon is used to specify the bound for a type
923928
parameter.
924929

925-
C# uses declaration-site variance using the keywords "in" and "out" for
930+
C# uses declaration-site variance using the keywords ``in`` and ``out`` for
926931
contravariance and covariance, respectively. By default, type parameters are
927932
invariant.
928933

929934
C# provides no way to specify a default type argument.
930935

931-
::
936+
.. code-block:: c#
932937
933938
// Generic class with bounds on type parameters
934939
public class ClassA<S, T>
@@ -951,20 +956,21 @@ TypeScript
951956
----------
952957

953958
TypeScript uses angle brackets to declare type parameters and for
954-
specialization. The "extends" keyword is used to specify a bound. It can be
955-
combined with other type operators such as "keyof".
959+
specialization. The ``extends`` keyword is used to specify a bound. It can be
960+
combined with other type operators such as ``keyof``.
956961

957962
TypeScript uses declaration-site variance. Variance is inferred from
958-
usage, not specified explicitly. TypeScript 4.7 will introduce the ability
959-
to specify variance using "in" and "out" keywords. This was added to handle
960-
extremely complex types where inference of variance was expensive.
963+
usage, not specified explicitly. TypeScript 4.7 introduced the ability
964+
to specify variance using ``in`` and ``out`` keywords. This was added to handle
965+
extremely complex types where inference of variance was expensive,
966+
yet the maintainers state that is useful for increasing readability.
961967

962-
A default type argument can be specified using the "=" operator.
968+
A default type argument can be specified using the ``=`` operator.
963969

964-
TypeScript supports the "type" keyword to declare a type alias, and this
970+
TypeScript supports the ``type`` keyword to declare a type alias, and this
965971
syntax supports generics.
966972

967-
::
973+
.. code-block:: typescript
968974
969975
// Generic interface
970976
interface InterfaceA<S, T extends SomeInterface1> {
@@ -991,19 +997,19 @@ Scala
991997
-----
992998

993999
In Scala, square brackets are used to declare type parameters. Square
994-
brackets are also used for specialization. The "<:" and ">:" operators
1000+
brackets are also used for specialization. The ``<:`` and ``>:`` operators
9951001
are used to specify upper and lower bounds, respectively.
9961002

9971003
Scala uses use-site variance but also allows declaration-site variance
998-
specification. It uses a "+" or "-" prefix operator for covariance and
1004+
specification. It uses a ``+`` or ``-`` prefix operator for covariance and
9991005
contravariance, respectively.
10001006

10011007
Scala provides no way to specify a default type argument.
10021008

10031009
It does support higher-kinded types (type parameters that accept type
10041010
type parameters).
10051011

1006-
::
1012+
.. code-block:: scala
10071013
10081014
10091015
// Generic class; type parameter has upper bound
@@ -1036,17 +1042,16 @@ Swift
10361042
Swift uses angle brackets to declare type parameters and for specialization.
10371043
The upper bound of a type parameter is specified using a colon.
10381044

1039-
Swift uses declaration-site variance, and variance of type parameters is
1040-
inferred from their usage.
1045+
Swift doesn't support generic variance; all type parameters are invariant.
10411046

10421047
Swift provides no way to specify a default type argument.
10431048

1044-
::
1049+
.. code-block:: swift
10451050
10461051
// Generic class
10471052
class ClassA<T> {
10481053
// Generic method
1049-
func method1<X>(val: T) -> S { }
1054+
func method1<X>(val: T) -> X { }
10501055
}
10511056
10521057
// Type parameter with upper bound constraint
@@ -1061,23 +1066,33 @@ Rust
10611066

10621067
Rust uses angle brackets to declare type parameters and for specialization.
10631068
The upper bound of a type parameter is specified using a colon. Alternatively
1064-
a "where" clause can specify various constraints.
1069+
a ``where`` clause can specify various constraints.
10651070

1066-
Rust uses declaration-site variance, and variance of type parameters is
1067-
typically inferred from their usage. In cases where a type parameter is not
1068-
used within a type, variance can be specified explicitly.
1071+
Rust does not have traditional object oriented inheritance or variance.
1072+
Subtyping in Rust is very restricted and occurs only due to variance with
1073+
respect to lifetimes.
10691074

1070-
A default type argument can be specified using the "=" operator.
1075+
A default type argument can be specified using the ``=`` operator.
10711076

1072-
::
1077+
.. code-block:: rust
10731078
10741079
// Generic class
1075-
struct StructA<T> {
1080+
struct StructA<T> { // T's lifetime is inferred as covariant
10761081
x: T
10771082
}
10781083
1084+
fn f<'a>(
1085+
mut short_lifetime: StructA<&'a i32>,
1086+
mut long_lifetime: StructA<&'static i32>,
1087+
) {
1088+
long_lifetime = short_lifetime;
1089+
// error: StructA<&'a i32> is not a subtype of StructA<&'static i32>
1090+
short_lifetime = long_lifetime;
1091+
// valid: StructA<&'static i32> is a subtype of StructA<&'a i32>
1092+
}
1093+
10791094
// Type parameter with bound
1080-
struct StructB<T: StructA> {}
1095+
struct StructB<T: SomeTrait> {}
10811096
10821097
// Type parameter with additional constraints
10831098
struct StructC<T>
@@ -1089,56 +1104,55 @@ A default type argument can be specified using the "=" operator.
10891104
// Generic function
10901105
fn func1<T>(val: &[T]) -> T { }
10911106
1092-
// Explicit variance specification
1093-
use type_variance::{Covariant, Contravariant};
1094-
1095-
struct StructD<A, R> {
1096-
arg: Covariant<A>,
1097-
ret: Contravariant<R>,
1098-
}
1099-
11001107
// Generic type alias
1101-
type MyType<T> = StructC<T>
1108+
type MyType<T> = StructC<T>;
11021109
11031110
11041111
Kotlin
11051112
------
11061113

11071114
Kotlin uses angle brackets to declare type parameters and for specialization.
1108-
The upper bound of a type is specified using a colon.
1115+
By default, type parameters are invariant. The upper bound of a type is
1116+
specified using a colon.
1117+
Alternatively, a ``where`` clause can specify various constraints.
11091118

11101119
Kotlin supports declaration-site variance where variance of type parameters is
1111-
explicitly declared using "in" and "out" keywords. It also supports use-site
1120+
explicitly declared using ``in`` and ``out`` keywords. It also supports use-site
11121121
variance which limits which methods and members can be used.
11131122

11141123
Kotlin provides no way to specify a default type argument.
11151124

1116-
::
1125+
.. code-block:: kotlin
11171126
11181127
// Generic class
1119-
class ClassA<T> { }
1128+
class ClassA<T>
11201129
11211130
// Type parameter with upper bound
1122-
class ClassB<T: SomeClass1> { }
1131+
class ClassB<T : SomeClass1>
11231132
11241133
// Contravariant and covariant type parameters
1125-
class ClassC<in S, out T> { }
1134+
class ClassC<in S, out T>
11261135
11271136
// Generic function
1128-
fun func1<T>() -> T {}
1137+
fun <T> func1(): T {
1138+
1139+
// Use site variance
1140+
val covariantA: ClassA<out Number>
1141+
val contravariantA: ClassA<in Number>
1142+
}
11291143
11301144
// Generic type alias
1131-
typealias<T> = ClassA<T>
1145+
typealias TypeAliasFoo<T> = ClassA<T>
11321146
11331147
11341148
Julia
11351149
-----
11361150

11371151
Julia uses curly braces to declare type parameters and for specialization.
1138-
The "<:" operator can be used within a "where" clause to declare
1152+
The ``<:`` operator can be used within a ``where`` clause to declare
11391153
upper and lower bounds on a type.
11401154

1141-
::
1155+
.. code-block:: julia
11421156
11431157
// Generic struct; type parameter with upper and lower bounds
11441158
struct StructA{T} where Int <: T <: Number
@@ -1151,6 +1165,62 @@ upper and lower bounds on a type.
11511165
// Alternate form of generic function
11521166
function func2(v::Container{T} where T <: Real)
11531167
1168+
Dart
1169+
----
1170+
1171+
Dart uses angle brackets to declare type parameters and for specialization.
1172+
The upper bound of a type is specified using the ``extends`` keyword.
1173+
By default, type parameters are covariant.
1174+
1175+
Dart supports declaration-site variance, where variance of type parameters is
1176+
explicitly declared using ``in``, ``out`` and ``inout`` keywords.
1177+
It does not support use-site variance.
1178+
1179+
Dart provides no way to specify a default type argument.
1180+
1181+
.. code-block:: dart
1182+
1183+
// Generic class
1184+
class ClassA<T> { }
1185+
1186+
// Type parameter with upper bound
1187+
class ClassB<T extends SomeClass1> { }
1188+
1189+
// Contravariant and covariant type parameters
1190+
class ClassC<in S, out T> { }
1191+
1192+
// Generic function
1193+
T func1<T>() { }
1194+
1195+
// Generic type alias
1196+
typedef TypeDefFoo<T> = ClassA<T>;
1197+
1198+
Go
1199+
--
1200+
1201+
Go uses square brackets to declare type parameters and for specialization.
1202+
The upper bound of a type is specified after the name of the parameter, and
1203+
must always be specified. The keyword ``any`` is used for an unbound type parameter.
1204+
1205+
Go doesn't support variance; all type parameters are invariant.
1206+
1207+
Go provides no way to specify a default type argument.
1208+
1209+
Go does not support generic type aliases.
1210+
1211+
.. code-block:: go
1212+
1213+
// Generic type without a bound
1214+
type TypeA[T any] struct {
1215+
t T
1216+
}
1217+
1218+
// Type parameter with upper bound
1219+
type TypeB[T SomeType1] struct { }
1220+
1221+
// Generic function
1222+
func func1[T any]() { }
1223+
11541224
11551225
Summary
11561226
-------
@@ -1162,7 +1232,8 @@ Summary
11621232
| C++ | template | n/a | n/a | = | n/a | n/a |
11631233
| | <> | | | | | |
11641234
+------------+----------+---------+--------+----------+-----------+-----------+
1165-
| Java | <> | extends | | | use | inferred |
1235+
| Java | <> | extends | | | use | super, |
1236+
| | | | | | | extends |
11661237
+------------+----------+---------+--------+----------+-----------+-----------+
11671238
| C# | <> | where | | | decl | in, out |
11681239
+------------+----------+---------+--------+----------+-----------+-----------+
@@ -1171,15 +1242,21 @@ Summary
11711242
+------------+----------+---------+--------+----------+-----------+-----------+
11721243
| Scala | [] | T <: X | T >: X | | use, decl | +, - |
11731244
+------------+----------+---------+--------+----------+-----------+-----------+
1174-
| Swift | <> | T: X | | | decl | inferred |
1245+
| Swift | <> | T: X | | | n/a | n/a |
11751246
+------------+----------+---------+--------+----------+-----------+-----------+
1176-
| Rust | <> | T: X, | | = | decl | inferred, |
1177-
| | | where | | | | explicit |
1247+
| Rust | <> | T: X, | | = | n/a | n/a |
1248+
| | | where | | | | |
11781249
+------------+----------+---------+--------+----------+-----------+-----------+
1179-
| Kotlin | <> | T: X | | | use, decl | inferred |
1250+
| Kotlin | <> | T: X, | | | use, decl | in, out |
1251+
| | | where | | | | |
11801252
+------------+----------+---------+--------+----------+-----------+-----------+
11811253
| Julia | {} | T <: X | X <: T | | n/a | n/a |
11821254
+------------+----------+---------+--------+----------+-----------+-----------+
1255+
| Dart | <> | extends | | | decl | in, out, |
1256+
| | | | | | | inout |
1257+
+------------+----------+---------+--------+----------+-----------+-----------+
1258+
| Go | [] | T X | | | n/a | n/a |
1259+
+------------+----------+---------+--------+----------+-----------+-----------+
11831260
| Python | [] | T: X | | | decl | inferred |
11841261
| (proposed) | | | | | | |
11851262
+------------+----------+---------+--------+----------+-----------+-----------+

0 commit comments

Comments
 (0)