@@ -859,10 +859,13 @@ \section{Overview}
859
859
Type annotations declare the types of
860
860
variables and functions (including methods and constructors).
861
861
\item
862
- %% TODO(eernst): Change when integrating instantiate-to-bounds.md.
863
862
Type annotations may be omitted, in which case they are generally
864
- filled in with the type \DYNAMIC{}
863
+ filled in using type inference, or using the type \DYNAMIC{}
865
864
(\ref{typeDynamic}).
865
+ \commentary{%
866
+ Type inference will be specified in a future version of this document
867
+ (\ref{overview}).%
868
+ }
866
869
\end{enumerate}%
867
870
}
868
871
@@ -7701,12 +7704,7 @@ \subsection{Instantiation to Bound}
7701
7704
For instance, with the declaration \code{Type listType() => List;},
7702
7705
evaluation of the raw type expression \code{List} in the body yields
7703
7706
an instance of class \code{Type} reifying \code{List<dynamic>},
7704
- because \code{List} is subject to instantiation to bound.
7705
- Note that \code{List<dynamic>} is not syntactically an expression,
7706
- but it is still possible to get access to
7707
- a \code{Type} instance reifying \code{List<dynamic>}
7708
- without instantiation to bound,
7709
- because it can be the value of a type variable.%
7707
+ because \code{List} is subject to instantiation to bound.%
7710
7708
}
7711
7709
7712
7710
\rationale{%
@@ -8421,7 +8419,9 @@ \subsection{Constants}
8421
8419
a mixin or a type alias that is not qualified by a deferred prefix,
8422
8420
is a potentially constant and constant expression.
8423
8421
\commentary{%
8424
- The constant expression always evaluates to a \code{Type} object.
8422
+ The constant expression always evaluates to a \code{Type} object
8423
+ which is a reified type
8424
+ (\ref{typeType}).
8425
8425
For example, if $C$ is the name of a class or type alias,
8426
8426
the expression \code{$C$} is a constant,
8427
8427
and if $C$ is imported with a prefix $p$, \code{$p$.$C$} is
@@ -17557,7 +17557,8 @@ \subsection{Identifier Reference}
17557
17557
\item
17558
17558
If $D$ is a class, mixin, or type alias,
17559
17559
the value of $e$ is an object implementing the class \code{Type}
17560
- which reifies the corresponding type.
17560
+ which reifies the corresponding type
17561
+ (\ref{typeType}).
17561
17562
\item
17562
17563
If $D$ is a type parameter $X$ then the value of $e$ is
17563
17564
the value of the actual type argument corresponding to $X$
@@ -21183,41 +21184,6 @@ \subsection{Dynamic Type System}
21183
21184
(\ref{actualTypes}).%
21184
21185
}
21185
21186
21186
- \LMHash{}%
21187
- When types are reified as instances of the built-in class \code{Type},
21188
- those objects override the \lit{==} operator
21189
- inherited from the \code{Object} class, so that
21190
- two \code{Type} objects are equal according to operator \lit{==}
21191
- if{}f the corresponding types are subtypes of each other.
21192
-
21193
- \commentary{%
21194
- For example, the \code{Type} objects for the types
21195
- \DYNAMIC{} and \code{Object} are equal to each other
21196
- and hence \code{dynamic\,==\,Object} must evaluate to \TRUE.
21197
- No constraints are imposed on the built-in function \code{identical},
21198
- so \code{identical(dynamic, Object)} may be \TRUE{} or \FALSE.
21199
-
21200
- Similarly, \code{Type} instances for distinct type alias declarations
21201
- declaring a name for the same function type are equal:%
21202
- }
21203
-
21204
- \begin{dartCode}
21205
- \TYPEDEF{} F = \VOID{} \FUNCTION{}<X>(X);
21206
- \TYPEDEF{} G = \VOID{} \FUNCTION{}<Y>(Y);
21207
- \\
21208
- \VOID{} main() \{
21209
- assert(F == G);
21210
- \}
21211
- \end{dartCode}
21212
-
21213
- \LMHash{}%
21214
- \commentary{%
21215
- Instances of \code{Type} can be obtained in various ways,
21216
- for example by using reflection,
21217
- by reading the \code{runtimeType} of an object,
21218
- or by evaluating a \emph{type literal} expression.%
21219
- }
21220
-
21221
21187
\LMHash{}%
21222
21188
An expression is a \emph{type literal} if it is an identifier,
21223
21189
or a qualified identifier,
@@ -23102,7 +23068,7 @@ \subsection{Type Never}
23102
23068
}
23103
23069
23104
23070
23105
- \subsection{Type \code{ Null} }
23071
+ \subsection{Type Null}
23106
23072
\LMLabel{typeNull}
23107
23073
23108
23074
\LMHash{}%
@@ -23148,6 +23114,109 @@ \subsection{Type \code{Null}}
23148
23114
}
23149
23115
23150
23116
23117
+ \subsection{Type Type}
23118
+ \LMLabel{typeType}
23119
+
23120
+ \LMHash{}%
23121
+ The Dart runtime supports a very limited kind of introspective reflection
23122
+ for all programs
23123
+ (\commentary{%
23124
+ that is, without including any reflection support mechanisms,
23125
+ e.g., importing \code{dart:mirrors},
23126
+ or using reflection related code generation%
23127
+ }).
23128
+ In particular, evaluation of a type literal as an expression yields
23129
+ an object whose run-time type is a subtype of the built-in type \code{Type}.
23130
+ System libraries may deliver such objects as well
23131
+ (\commentary{e.g., the method \code{runtimeType} on \code{Object}}).
23132
+ If an object $o$ is obtained in this manner
23133
+ as a reification of the Dart type $T$,
23134
+ we say that $o$ is a \Index{reified type},
23135
+ and we say that $o$ \IndexCustom{reifies}{type!reifies} $T$.
23136
+
23137
+ %% TODO(eernst): Define "same type" in one location in this spec, use it here.
23138
+ \LMHash{}%
23139
+ A reified type identifies the underlying Dart type in the sense that
23140
+ it supports equality tests with other reified types as follows.
23141
+ Let $o_1$ and $o_2$ be reified types that reify $S_1$ respectively $S_2$,
23142
+ and let $o_3$ be an object which is not a reified type.
23143
+ Let $U_j$ be the transitive alias expansion of $S_j$, for $j \in 1 .. 3$,
23144
+ and let $v_j$ be a fresh variable whose value is $o_j$, for $j \in 1 .. 3$.
23145
+ It is then guaranteed that \code{$v_1$ == $v_2$} if{}f
23146
+ \NormalizedTypeOf{$U_1$} and \NormalizedTypeOf{$U_2$}
23147
+ are syntactically equal,
23148
+ up to equivalence of bound variables
23149
+ and up to designations of the same type using different syntax
23150
+ (\commentary{e.g., \code{C} and \code{prefix.C} may denote the same type}).
23151
+ Conversely, \code{$v_1$ == $v_3$} will yield false.
23152
+
23153
+ \commentary{%
23154
+ Note that we do not equate primitive top types.
23155
+ For example,
23156
+ reified types reifying \code{List<\VOID>} and \code{List<\DYNAMIC>}
23157
+ are not equal.
23158
+ However, a type variable which is declared by a function type
23159
+ is treated as if it were consistently renamed to a fresh name,
23160
+ thus making types identical if possible
23161
+ (also known as alpha equivalence).
23162
+ For example:%
23163
+ }
23164
+
23165
+ \begin{dartCode}
23166
+ \TYPEDEF{} F = \VOID{} \FUNCTION{}<X>(X);
23167
+ \TYPEDEF{} G = \VOID{} \FUNCTION{}<Y>(Y);
23168
+ \\
23169
+ \VOID{} main() \{
23170
+ print(F == G); // \comment{Prints 'true'.}
23171
+ \}
23172
+ \end{dartCode}
23173
+
23174
+ \commentary{%
23175
+ Note that reified types have a primitive operator \lit{==}
23176
+ (\ref{theOperatorEqualsEquals}).
23177
+ This property cannot be assumed for arbitrary expressions of type \code{Type}.
23178
+ For instance, we can declare
23179
+ \code{\CLASS\,\,MyType\,\,\EXTENDS\,\,Type \{\ldots\}}
23180
+ and override operator \lit{==}.%
23181
+ }
23182
+
23183
+ \LMHash{}%
23184
+ Let $e_1$ and $e_2$ be constant expressions
23185
+ (\ref{constants})
23186
+ evaluating to $o_1$ respectively $o_2$,
23187
+ which are reified types reifying the Dart types $S_1$ respecively $S_2$.
23188
+ Let $v_1$ and $v_2$ be fresh variables bound to $o_1$ respectively $o_2$
23189
+ We then have \code{identical($v_1$, $v_2$)} if{}f
23190
+ \code{$S_1$\,\,==\,\,$S_2$}.
23191
+
23192
+ \commentary{%
23193
+ In other words, constant reified types are canonicalized.
23194
+ For runtime implementations which implement identity by choosing a
23195
+ canonical representative for the equivalence class of equal instances,
23196
+ the choice of what type object to canonicalize to is not
23197
+ observable in the language.
23198
+ }
23199
+
23200
+ \rationale{%
23201
+ As mentioned at the beginning of this section,
23202
+ reified types support a very limited kind of introspective reflection.
23203
+ In particular, we can compare reified types for equality,
23204
+ and in the case where two reified types are equal
23205
+ it is known that they reify types which are subtypes of each other
23206
+ (that is, they are ``the same type'' with respect to subtyping).
23207
+ But we cannot compare reified types for any inequality, that is,
23208
+ we cannot determine whether one is a subtype of the other.
23209
+ It is also impossible to deconstruct a reified type.
23210
+ E.g., we cannot obtain the reified type for \code{$T$}
23211
+ by performing operations on a given reified type for \code{List<$T$>}.
23212
+ This design was chosen in order to ensure that Dart programs
23213
+ do not incur the substantial implications in terms of
23214
+ program size and run-time performance
23215
+ that are very difficult to avoid
23216
+ when a more powerful form of reflection is supported.%
23217
+ }
23218
+
23219
+
23151
23220
\subsection{Function Types}
23152
23221
\LMLabel{functionTypes}
23153
23222
@@ -23200,7 +23269,7 @@ \subsection{Function Types}
23200
23269
}
23201
23270
23202
23271
23203
- \subsection{Type \FUNCTION }
23272
+ \subsection{Type Function }
23204
23273
\LMLabel{functionType}
23205
23274
23206
23275
\LMHash{}%
@@ -23241,7 +23310,7 @@ \subsection{Type \FUNCTION}
23241
23310
}
23242
23311
23243
23312
23244
- \subsection{Type \DYNAMIC }
23313
+ \subsection{Type dynamic }
23245
23314
\LMLabel{typeDynamic}
23246
23315
23247
23316
\LMHash{}%
@@ -24372,44 +24441,20 @@ \subsubsection{Null promotion}
24372
24441
These are extended as per
24373
24442
[separate proposal](https://github.com/dart-lang/language/blob/master/resources/type-system/flow-analysis.md).
24374
24443
24375
- \subsubsection{Runtime type equality operator}
24376
-
24377
- !!!TODO!!!
24378
-
24379
- Two objects $T_1$ and $T_2$ which are instances of \code{Type} (that
24380
- is, runtime type objects) are considered equal if and only if the
24381
- runtime type objects $T_1$ and $T_2$ corresponds to the types $S_1$
24382
- and $S_2$ respectively, and the normal forms \NormalizedTypeOf{$S_1$}
24383
- and \NormalizedTypeOf{$S_2$} are syntactically equal up to equivalence
24384
- of bound variables. Note that we do not equate primitive top types.
24385
- \code{List<\VOID>} and \code{List<\DYNAMIC>} are still considered
24386
- distinct runtime type objects. Note that we also do not equate
24387
- function types which differ in the placement of \REQUIRED{} on
24388
- parameter types.
24389
-
24390
- \subsubsection{Constant evaluation and canonicalization}
24391
-
24392
- \paragraph{Type literals}
24393
-
24394
- Two constant type literals $T_1$ and $T_2$ compare as identical if they
24395
- are equal using the definition of runtime type equality specified above.
24396
-
24397
- For runtime implementations which implement identity by choosing a
24398
- canonical representative for the equivalence class of equal instances,
24399
- the choice of what type object to canonicalize to is not
24400
- observable in the language.
24401
24444
24402
24445
\paragraph{Constant instances}
24403
24446
24404
- Any two
24405
- instances which are otherwise identical except for their generic type arguments
24406
- shall be considered identical if those generic type arguments compare equal
24407
- using the definition of runtime type object equality defined above. That is,
24408
- comparison (or canonicalization) of constant instances of generic classes is
24409
- performed relative to the normal forms of their generic type arguments.
24410
- Hence, an instance of
24411
- \code{$C$<$T_0$>} compares identical to \code{C<$T_1$>} if $T_0$ and $T_1$ have the same normal form
24412
- (up to the identity of bound variables), and the objects are otherwise
24447
+ !!!TODO!!!
24448
+
24449
+ Any two instances which are otherwise identical except for their
24450
+ generic type arguments shall be considered identical if those generic
24451
+ type arguments compare equal using the definition of runtime type
24452
+ object equality defined above. That is, comparison (or
24453
+ canonicalization) of constant instances of generic classes is
24454
+ performed relative to the normal forms of their generic type
24455
+ arguments. Hence, an instance of \code{$C$<$T_0$>} compares identical
24456
+ to \code{C<$T_1$>} if $T_0$ and $T_1$ have the same normal form (up to
24457
+ the identity of bound variables), and the objects are otherwise
24413
24458
identical.
24414
24459
24415
24460
Implementations of the Dart runtime semantics rely on canonicalization of
0 commit comments