@@ -851,10 +851,13 @@ \section{Overview}
851
851
Type annotations declare the types of
852
852
variables and functions (including methods and constructors).
853
853
\item
854
- %% TODO(eernst): Change when integrating instantiate-to-bounds.md.
855
854
Type annotations may be omitted, in which case they are generally
856
- filled in with the type \DYNAMIC{}
855
+ filled in using type inference, or using the type \DYNAMIC{}
857
856
(\ref{typeDynamic}).
857
+ \commentary{%
858
+ Type inference will be specified in a future version of this document
859
+ (\ref{overview}).%
860
+ }
858
861
\end{enumerate}%
859
862
}
860
863
@@ -7693,12 +7696,7 @@ \subsection{Instantiation to Bound}
7693
7696
For instance, with the declaration \code{Type listType() => List;},
7694
7697
evaluation of the raw type expression \code{List} in the body yields
7695
7698
an instance of class \code{Type} reifying \code{List<dynamic>},
7696
- because \code{List} is subject to instantiation to bound.
7697
- Note that \code{List<dynamic>} is not syntactically an expression,
7698
- but it is still possible to get access to
7699
- a \code{Type} instance reifying \code{List<dynamic>}
7700
- without instantiation to bound,
7701
- because it can be the value of a type variable.%
7699
+ because \code{List} is subject to instantiation to bound.%
7702
7700
}
7703
7701
7704
7702
\rationale{%
@@ -8413,7 +8411,9 @@ \subsection{Constants}
8413
8411
a mixin or a type alias that is not qualified by a deferred prefix,
8414
8412
is a potentially constant and constant expression.
8415
8413
\commentary{%
8416
- The constant expression always evaluates to a \code{Type} object.
8414
+ The constant expression always evaluates to a \code{Type} object
8415
+ which is a reified type
8416
+ (\ref{typeType}).
8417
8417
For example, if $C$ is the name of a class or type alias,
8418
8418
the expression \code{$C$} is a constant,
8419
8419
and if $C$ is imported with a prefix $p$, \code{$p$.$C$} is
@@ -17435,7 +17435,8 @@ \subsection{Identifier Reference}
17435
17435
\item
17436
17436
If $D$ is a class, mixin, or type alias,
17437
17437
the value of $e$ is an object implementing the class \code{Type}
17438
- which reifies the corresponding type.
17438
+ which reifies the corresponding type
17439
+ (\ref{typeType}).
17439
17440
\item
17440
17441
If $D$ is a type parameter $X$ then the value of $e$ is
17441
17442
the value of the actual type argument corresponding to $X$
@@ -21045,41 +21046,6 @@ \subsection{Dynamic Type System}
21045
21046
(\ref{actualTypes}).%
21046
21047
}
21047
21048
21048
- \LMHash{}%
21049
- When types are reified as instances of the built-in class \code{Type},
21050
- those objects override the \lit{==} operator
21051
- inherited from the \code{Object} class, so that
21052
- two \code{Type} objects are equal according to operator \lit{==}
21053
- if{}f the corresponding types are subtypes of each other.
21054
-
21055
- \commentary{%
21056
- For example, the \code{Type} objects for the types
21057
- \DYNAMIC{} and \code{Object} are equal to each other
21058
- and hence \code{dynamic\,==\,Object} must evaluate to \TRUE.
21059
- No constraints are imposed on the built-in function \code{identical},
21060
- so \code{identical(dynamic, Object)} may be \TRUE{} or \FALSE.
21061
-
21062
- Similarly, \code{Type} instances for distinct type alias declarations
21063
- declaring a name for the same function type are equal:%
21064
- }
21065
-
21066
- \begin{dartCode}
21067
- \TYPEDEF{} F = \VOID{} \FUNCTION{}<X>(X);
21068
- \TYPEDEF{} G = \VOID{} \FUNCTION{}<Y>(Y);
21069
- \\
21070
- \VOID{} main() \{
21071
- assert(F == G);
21072
- \}
21073
- \end{dartCode}
21074
-
21075
- \LMHash{}%
21076
- \commentary{%
21077
- Instances of \code{Type} can be obtained in various ways,
21078
- for example by using reflection,
21079
- by reading the \code{runtimeType} of an object,
21080
- or by evaluating a \emph{type literal} expression.%
21081
- }
21082
-
21083
21049
\LMHash{}%
21084
21050
An expression is a \emph{type literal} if it is an identifier,
21085
21051
or a qualified identifier,
@@ -22964,7 +22930,7 @@ \subsection{Type Never}
22964
22930
}
22965
22931
22966
22932
22967
- \subsection{Type \code{ Null} }
22933
+ \subsection{Type Null}
22968
22934
\LMLabel{typeNull}
22969
22935
22970
22936
\LMHash{}%
@@ -23010,6 +22976,109 @@ \subsection{Type \code{Null}}
23010
22976
}
23011
22977
23012
22978
22979
+ \subsection{Type Type}
22980
+ \LMLabel{typeType}
22981
+
22982
+ \LMHash{}%
22983
+ The Dart runtime supports a very limited kind of introspective reflection
22984
+ for all programs
22985
+ (\commentary{%
22986
+ that is, without including any reflection support mechanisms,
22987
+ e.g., importing \code{dart:mirrors},
22988
+ or using reflection related code generation%
22989
+ }).
22990
+ In particular, evaluation of a type literal as an expression yields
22991
+ an object whose run-time type is a subtype of the built-in type \code{Type}.
22992
+ System libraries may deliver such objects as well
22993
+ (\commentary{e.g., the method \code{runtimeType} on \code{Object}}).
22994
+ If an object $o$ is obtained in this manner
22995
+ as a reification of the Dart type $T$,
22996
+ we say that $o$ is a \Index{reified type},
22997
+ and we say that $o$ \IndexCustom{reifies}{type!reifies} $T$.
22998
+
22999
+ %% TODO(eernst): Define "same type" in one location in this spec, use it here.
23000
+ \LMHash{}%
23001
+ A reified type identifies the underlying Dart type in the sense that
23002
+ it supports equality tests with other reified types as follows.
23003
+ Let $o_1$ and $o_2$ be reified types that reify $S_1$ respectively $S_2$,
23004
+ and let $o_3$ be an object which is not a reified type.
23005
+ Let $U_j$ be the transitive alias expansion of $S_j$, for $j \in 1 .. 3$,
23006
+ and let $v_j$ be a fresh variable whose value is $o_j$, for $j \in 1 .. 3$.
23007
+ It is then guaranteed that \code{$v_1$ == $v_2$} if{}f
23008
+ \NormalizedTypeOf{$U_1$} and \NormalizedTypeOf{$U_2$}
23009
+ are syntactically equal,
23010
+ up to equivalence of bound variables
23011
+ and up to designations of the same type using different syntax
23012
+ (\commentary{e.g., \code{C} and \code{prefix.C} may denote the same type}).
23013
+ Conversely, \code{$v_1$ == $v_3$} will yield false.
23014
+
23015
+ \commentary{%
23016
+ Note that we do not equate primitive top types.
23017
+ For example,
23018
+ reified types reifying \code{List<\VOID>} and \code{List<\DYNAMIC>}
23019
+ are not equal.
23020
+ However, a type variable which is declared by a function type
23021
+ is treated as if it were consistently renamed to a fresh name,
23022
+ thus making types identical if possible
23023
+ (also known as alpha equivalence).
23024
+ For example:%
23025
+ }
23026
+
23027
+ \begin{dartCode}
23028
+ \TYPEDEF{} F = \VOID{} \FUNCTION{}<X>(X);
23029
+ \TYPEDEF{} G = \VOID{} \FUNCTION{}<Y>(Y);
23030
+ \\
23031
+ \VOID{} main() \{
23032
+ print(F == G); // \comment{Prints 'true'.}
23033
+ \}
23034
+ \end{dartCode}
23035
+
23036
+ \commentary{%
23037
+ Note that reified types have a primitive operator \lit{==}
23038
+ (\ref{theOperatorEqualsEquals}).
23039
+ This property cannot be assumed for arbitrary expressions of type \code{Type}.
23040
+ For instance, we can declare
23041
+ \code{\CLASS\,\,MyType\,\,\EXTENDS\,\,Type \{\ldots\}}
23042
+ and override operator \lit{==}.%
23043
+ }
23044
+
23045
+ \LMHash{}%
23046
+ Let $e_1$ and $e_2$ be constant expressions
23047
+ (\ref{constants})
23048
+ evaluating to $o_1$ respectively $o_2$,
23049
+ which are reified types reifying the Dart types $S_1$ respecively $S_2$.
23050
+ Let $v_1$ and $v_2$ be fresh variables bound to $o_1$ respectively $o_2$
23051
+ We then have \code{identical($v_1$, $v_2$)} if{}f
23052
+ \code{$S_1$\,\,==\,\,$S_2$}.
23053
+
23054
+ \commentary{%
23055
+ In other words, constant reified types are canonicalized.
23056
+ For runtime implementations which implement identity by choosing a
23057
+ canonical representative for the equivalence class of equal instances,
23058
+ the choice of what type object to canonicalize to is not
23059
+ observable in the language.
23060
+ }
23061
+
23062
+ \rationale{%
23063
+ As mentioned at the beginning of this section,
23064
+ reified types support a very limited kind of introspective reflection.
23065
+ In particular, we can compare reified types for equality,
23066
+ and in the case where two reified types are equal
23067
+ it is known that they reify types which are subtypes of each other
23068
+ (that is, they are ``the same type'' with respect to subtyping).
23069
+ But we cannot compare reified types for any inequality, that is,
23070
+ we cannot determine whether one is a subtype of the other.
23071
+ It is also impossible to deconstruct a reified type.
23072
+ E.g., we cannot obtain the reified type for \code{$T$}
23073
+ by performing operations on a given reified type for \code{List<$T$>}.
23074
+ This design was chosen in order to ensure that Dart programs
23075
+ do not incur the substantial implications in terms of
23076
+ program size and run-time performance
23077
+ that are very difficult to avoid
23078
+ when a more powerful form of reflection is supported.%
23079
+ }
23080
+
23081
+
23013
23082
\subsection{Function Types}
23014
23083
\LMLabel{functionTypes}
23015
23084
@@ -23062,7 +23131,7 @@ \subsection{Function Types}
23062
23131
}
23063
23132
23064
23133
23065
- \subsection{Type \FUNCTION }
23134
+ \subsection{Type Function }
23066
23135
\LMLabel{functionType}
23067
23136
23068
23137
\LMHash{}%
@@ -23103,7 +23172,7 @@ \subsection{Type \FUNCTION}
23103
23172
}
23104
23173
23105
23174
23106
- \subsection{Type \DYNAMIC }
23175
+ \subsection{Type dynamic }
23107
23176
\LMLabel{typeDynamic}
23108
23177
23109
23178
\LMHash{}%
@@ -24233,44 +24302,20 @@ \subsubsection{Null promotion}
24233
24302
These are extended as per
24234
24303
[separate proposal](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md).
24235
24304
24236
- \subsubsection{Runtime type equality operator}
24237
-
24238
- !!!TODO!!!
24239
-
24240
- Two objects $T_1$ and $T_2$ which are instances of \code{Type} (that
24241
- is, runtime type objects) are considered equal if and only if the
24242
- runtime type objects $T_1$ and $T_2$ corresponds to the types $S_1$
24243
- and $S_2$ respectively, and the normal forms \NormalizedTypeOf{$S_1$}
24244
- and \NormalizedTypeOf{$S_2$} are syntactically equal up to equivalence
24245
- of bound variables. Note that we do not equate primitive top types.
24246
- \code{List<\VOID>} and \code{List<\DYNAMIC>} are still considered
24247
- distinct runtime type objects. Note that we also do not equate
24248
- function types which differ in the placement of \REQUIRED{} on
24249
- parameter types.
24250
-
24251
- \subsubsection{Constant evaluation and canonicalization}
24252
-
24253
- \paragraph{Type literals}
24254
-
24255
- Two constant type literals $T_1$ and $T_2$ compare as identical if they
24256
- are equal using the definition of runtime type equality specified above.
24257
-
24258
- For runtime implementations which implement identity by choosing a
24259
- canonical representative for the equivalence class of equal instances,
24260
- the choice of what type object to canonicalize to is not
24261
- observable in the language.
24262
24305
24263
24306
\paragraph{Constant instances}
24264
24307
24265
- Any two
24266
- instances which are otherwise identical except for their generic type arguments
24267
- shall be considered identical if those generic type arguments compare equal
24268
- using the definition of runtime type object equality defined above. That is,
24269
- comparison (or canonicalization) of constant instances of generic classes is
24270
- performed relative to the normal forms of their generic type arguments.
24271
- Hence, an instance of
24272
- \code{$C$<$T_0$>} compares identical to \code{C<$T_1$>} if $T_0$ and $T_1$ have the same normal form
24273
- (up to the identity of bound variables), and the objects are otherwise
24308
+ !!!TODO!!!
24309
+
24310
+ Any two instances which are otherwise identical except for their
24311
+ generic type arguments shall be considered identical if those generic
24312
+ type arguments compare equal using the definition of runtime type
24313
+ object equality defined above. That is, comparison (or
24314
+ canonicalization) of constant instances of generic classes is
24315
+ performed relative to the normal forms of their generic type
24316
+ arguments. Hence, an instance of \code{$C$<$T_0$>} compares identical
24317
+ to \code{C<$T_1$>} if $T_0$ and $T_1$ have the same normal form (up to
24318
+ the identity of bound variables), and the objects are otherwise
24274
24319
identical.
24275
24320
24276
24321
Implementations of the Dart runtime semantics rely on canonicalization of
0 commit comments