@@ -23323,12 +23323,13 @@ \subsubsection{The Canonical Syntax of Types}
23323
23323
\rationale{%
23324
23324
This shows that concrete syntax behaves in such a manner that it is
23325
23325
unsafe to consider two types as the same type,
23326
- based on the fact that they are denoted by the same syntax.
23326
+ based on the fact that they are denoted by the same syntax,
23327
+ even during the static analysis of a single expression.
23327
23328
23328
23329
Similarly, it is incorrect to consider two terms derived from \synt{type}
23329
- as different types based on the fact that they are syntactically different,
23330
- as they could in fact be the same type,
23331
- e.g., imported with different import prefixes.%
23330
+ as different types based on the fact that they are syntactically different.
23331
+ They could in fact be the same type,
23332
+ e.g., imported with different import prefixes.
23332
23333
23333
23334
Consequently, we introduce the notion of the canonical syntax for a type,
23334
23335
which has the property that each type has a unique syntactic form.
@@ -23344,49 +23345,63 @@ \subsubsection{The Canonical Syntax of Types}
23344
23345
of the types in a given library $L_1$
23345
23346
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23346
23347
one or more import links,
23347
- first choose a set of distinct fresh identifiers
23348
+ first choose a set of distinct, globally fresh identifiers
23348
23349
\List{\metavar{prefix}}{1}{n}.
23349
- Then transform each library $L_i$, $i \in 1 .. n$,
23350
- such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
23351
- and $L_i$ imports \code{dart:core} explicitly
23352
- with the suitable prefix $\metavar{prefix}_j$ for some $j$,
23353
- and change all existing imports to use the prefix
23354
- corresponding to the library which is being imported.
23350
+ Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23355
23351
23356
- \LMHash{}%
23357
- Next, transform every identifier expression and every \synt{typeName}
23358
- that refers to an imported declaration or a library declaration
23359
- such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23360
- and such that every name resolves to the same declaration
23361
- as it did in the original program.
23352
+ \begin{enumerate}
23353
+ \item
23354
+ Add a set of import directives to $L_i$ that imports
23355
+ each of the libraries \List{L}{1}{n} with
23356
+ the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23357
+
23358
+ \commentary{%
23359
+ This means that every library in the set
23360
+ $\{\,\List{L}{1}{n}\,\}$
23361
+ imports every other library in that set,
23362
+ even itself and system libraries like \code{dart:core}.%
23363
+ }
23364
+ \item
23365
+ Let \id{} be a non-private identifier that resolves to
23366
+ a library declaration in the library $L_j$ in the original program;
23367
+ \id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23368
+ Let \code{$p$.\id} be a qualified identifier where $p$ is
23369
+ an import prefix in the original program,
23370
+ \id{} is a non-private identifier,
23371
+ and \code{$p$.\id} resolves to
23372
+ a library declaration in the library $L_j$ in the original program;
23373
+ \code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23374
+ \item
23375
+ %% TODO(eernst): We should rename private names to fresh public names.
23376
+ Replace every type that denotes a type alias
23377
+ by its transitive alias expansion
23378
+ (\ref{typedef}).
23379
+ \commentary{%
23380
+ Note that the bodies of type alias declarations
23381
+ already use the new prefixes,
23382
+ so the results of the alias expansion will also use
23383
+ the new prefixes consistently.%
23384
+ }
23385
+ \end{enumerate}
23362
23386
23363
23387
\commentary{%
23364
23388
Note that this transformation does not change any occurrence of \VOID;
23365
- \VOID{} is a reserved word
23366
- and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23367
- }
23389
+ \VOID{} is a reserved word, not an identifier.
23390
+ Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23368
23391
23369
- %% TODO(eernst), for review: Rename private names to fresh public names?
23370
- %% Otherwise the type alias could turn into a term containing private names
23371
- %% from different libraries.
23372
- \LMHash{}%
23373
- Finally, replace every type that denotes a type alias
23374
- by its transitive alias expansion
23375
- (\ref{typedef}).
23376
- \commentary{%
23377
- Note that the bodies of type alias declarations already use the new prefixes,
23378
- so the results of the alias expansion will also use
23379
- the new prefixes consistently.%
23392
+ The transformation also does not change identifiers denoting type variables,
23393
+ There is no need to change those identifiers, because
23394
+ no occurrence of such an identifier resolves to a declaration in a
23395
+ different library.%
23396
+ %% TODO(eernst): Sort out the treatment of private identifiers, too.
23380
23397
}
23381
23398
23382
23399
\LMHash{}%
23383
- Every \synt{type} and type literal in the resulting program
23384
- is now expressed in a globally unique syntactic form.
23385
-
23386
- \rationale{%
23387
- This means that two terms denoting a type will have the same syntactic form
23388
- if and only if they denote the same type.
23389
- }
23400
+ Every \synt{type} and type literal in the resulting set of libraries
23401
+ is now expressed in a globally unique syntactic form,
23402
+ which is the form that we call the
23403
+ \IndexCustom{canonical syntax of}{type!canonical syntax of}
23404
+ said types.
23390
23405
23391
23406
\LMHash{}%
23392
23407
When we say that two types $T_1$ and $T_2$ have the
@@ -23396,6 +23411,36 @@ \subsubsection{The Canonical Syntax of Types}
23396
23411
have been transformed as described above,
23397
23412
and the resulting canonical syntaxes are identical.
23398
23413
23414
+ \rationale{%
23415
+ The transformation described here would not be useful in practice
23416
+ (or even possible---we can't edit \code{dart:core}).
23417
+ It only serves to show that we can express types using a syntactic form
23418
+ which is independent of the location.
23419
+ This is in turn needed in order to ensure that operations are well-defined
23420
+ even when they bring syntactic elements from different locations together,
23421
+ such as computations of subtype relationships,
23422
+ and construction of standard upper or lower bounds.
23423
+
23424
+ We could just as well have replaced the concrete syntax by a semantic
23425
+ notion of types,
23426
+ where each entity that denotes a type would be, in some sense,
23427
+ a reference to a specific declaration
23428
+ (this is likely to be the approach used by tool implementations).
23429
+ However, that approach would be somewhat inconvenient in a specification,
23430
+ because we would need to re-build all the structures that the
23431
+ syntax offers.
23432
+ For instance, we would need to support the construction of
23433
+ a semantic type entity for \code{Map<int, String>},
23434
+ based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
23435
+ and we would need to support deconstruction of those entities
23436
+ in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
23437
+ This would give rise to a lot of mechanism that will simply duplicate
23438
+ the structure of the syntax.
23439
+ So we prefer to show that the syntax \emph{can} be location independent,
23440
+ and that's sufficient to make syntax usable as our representation of
23441
+ static semantic types.%
23442
+ }
23443
+
23399
23444
23400
23445
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23401
23446
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -26119,7 +26164,7 @@ \section*{Appendix: Algorithmic Subtyping}
26119
26164
\item
26120
26165
\textbf{Reflexivity:}
26121
26166
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
26122
-
26167
+
26123
26168
\commentary{%
26124
26169
Note that this check is necessary as the base case for primitive types,
26125
26170
and type variables, but not for composite types.
@@ -26135,7 +26180,7 @@ \section*{Appendix: Algorithmic Subtyping}
26135
26180
\item
26136
26181
\textbf{Left Top:}
26137
26182
if $T_0$ is \DYNAMIC{} or \VOID{}
26138
- then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
26183
+ then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
26139
26184
\item
26140
26185
\textbf{Left Bottom:}
26141
26186
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -26171,8 +26216,7 @@ \section*{Appendix: Algorithmic Subtyping}
26171
26216
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
26172
26217
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
26173
26218
\item
26174
- if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
26175
- then the query is true.
26219
+ if $T_1$ is \code{$S$?} for some $S$ then the query is true.
26176
26220
\item
26177
26221
Otherwise, the query is false.
26178
26222
\end{itemize}
@@ -26215,7 +26259,7 @@ \section*{Appendix: Algorithmic Subtyping}
26215
26259
\begin{itemize}
26216
26260
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
26217
26261
\item or \SubtypeNE{T_0}{S_1}.
26218
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26262
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26219
26263
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26220
26264
\end{itemize}
26221
26265
\item
@@ -26225,7 +26269,7 @@ \section*{Appendix: Algorithmic Subtyping}
26225
26269
\begin{itemize}
26226
26270
\item either \SubtypeNE{T_0}{S_1}.
26227
26271
\item or \SubtypeNE{T_0}{\code{Null}}.
26228
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26272
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26229
26273
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26230
26274
\end{itemize}
26231
26275
\item
@@ -26263,7 +26307,10 @@ \section*{Appendix: Algorithmic Subtyping}
26263
26307
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
26264
26308
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
26265
26309
26266
- where each of the following hold:
26310
+ such that each of the following criteria is satisfied,
26311
+ where the $Z_i$ are fresh type variables with bounds
26312
+ $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
26313
+
26267
26314
\begin{itemize}
26268
26315
\item $p \geq n$.
26269
26316
\item $m \geq q$.
@@ -26272,8 +26319,6 @@ \section*{Appendix: Algorithmic Subtyping}
26272
26319
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
26273
26320
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
26274
26321
have the same canonical syntax, for $i \in 0 .. k$.
26275
- \item where the $Z_i$ are fresh type variables with bounds
26276
- $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
26277
26322
\end{itemize}
26278
26323
\item
26279
26324
\textbf{Named Function Types:}
@@ -26283,7 +26328,7 @@ \section*{Appendix: Algorithmic Subtyping}
26283
26328
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
26284
26329
$X_k$\,\EXTENDS\,$B_{0k}$>(%
26285
26330
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
26286
- \{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26331
+ \{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26287
26332
26288
26333
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
26289
26334
and $T_1$ is
@@ -26292,7 +26337,7 @@ \section*{Appendix: Algorithmic Subtyping}
26292
26337
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
26293
26338
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
26294
26339
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
26295
- \{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26340
+ \{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26296
26341
26297
26342
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
26298
26343
and the following criteria are all satisfied,
0 commit comments