@@ -23506,12 +23506,13 @@ \subsubsection{The Canonical Syntax of Types}
23506
23506
\rationale{%
23507
23507
This shows that concrete syntax behaves in such a manner that it is
23508
23508
unsafe to consider two types as the same type,
23509
- based on the fact that they are denoted by the same syntax.
23509
+ based on the fact that they are denoted by the same syntax,
23510
+ even during the static analysis of a single expression.
23510
23511
23511
23512
Similarly, it is incorrect to consider two terms derived from \synt{type}
23512
- as different types based on the fact that they are syntactically different,
23513
- as they could in fact be the same type,
23514
- e.g., imported with different import prefixes.%
23513
+ as different types based on the fact that they are syntactically different.
23514
+ They could in fact be the same type,
23515
+ e.g., imported with different import prefixes.
23515
23516
23516
23517
Consequently, we introduce the notion of the canonical syntax for a type,
23517
23518
which has the property that each type has a unique syntactic form.
@@ -23527,49 +23528,63 @@ \subsubsection{The Canonical Syntax of Types}
23527
23528
of the types in a given library $L_1$
23528
23529
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23529
23530
one or more import links,
23530
- first choose a set of distinct fresh identifiers
23531
+ first choose a set of distinct, globally fresh identifiers
23531
23532
\List{\metavar{prefix}}{1}{n}.
23532
- Then transform each library $L_i$, $i \in 1 .. n$,
23533
- such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
23534
- and $L_i$ imports \code{dart:core} explicitly
23535
- with the suitable prefix $\metavar{prefix}_j$ for some $j$,
23536
- and change all existing imports to use the prefix
23537
- corresponding to the library which is being imported.
23533
+ Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23538
23534
23539
- \LMHash{}%
23540
- Next, transform every identifier expression and every \synt{typeName}
23541
- that refers to an imported declaration or a library declaration
23542
- such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23543
- and such that every name resolves to the same declaration
23544
- as it did in the original program.
23535
+ \begin{enumerate}
23536
+ \item
23537
+ Add a set of import directives to $L_i$ that imports
23538
+ each of the libraries \List{L}{1}{n} with
23539
+ the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23540
+
23541
+ \commentary{%
23542
+ This means that every library in the set
23543
+ $\{\,\List{L}{1}{n}\,\}$
23544
+ imports every other library in that set,
23545
+ even itself and system libraries like \code{dart:core}.%
23546
+ }
23547
+ \item
23548
+ Let \id{} be a non-private identifier that resolves to
23549
+ a library declaration in the library $L_j$ in the original program;
23550
+ \id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23551
+ Let \code{$p$.\id} be a qualified identifier where $p$ is
23552
+ an import prefix in the original program,
23553
+ \id{} is a non-private identifier,
23554
+ and \code{$p$.\id} resolves to
23555
+ a library declaration in the library $L_j$ in the original program;
23556
+ \code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23557
+ \item
23558
+ %% TODO(eernst): We should rename private names to fresh public names.
23559
+ Replace every type that denotes a type alias
23560
+ by its transitive alias expansion
23561
+ (\ref{typedef}).
23562
+ \commentary{%
23563
+ Note that the bodies of type alias declarations
23564
+ already use the new prefixes,
23565
+ so the results of the alias expansion will also use
23566
+ the new prefixes consistently.%
23567
+ }
23568
+ \end{enumerate}
23545
23569
23546
23570
\commentary{%
23547
23571
Note that this transformation does not change any occurrence of \VOID;
23548
- \VOID{} is a reserved word
23549
- and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23550
- }
23572
+ \VOID{} is a reserved word, not an identifier.
23573
+ Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23551
23574
23552
- %% TODO(eernst), for review: Rename private names to fresh public names?
23553
- %% Otherwise the type alias could turn into a term containing private names
23554
- %% from different libraries.
23555
- \LMHash{}%
23556
- Finally, replace every type that denotes a type alias
23557
- by its transitive alias expansion
23558
- (\ref{typedef}).
23559
- \commentary{%
23560
- Note that the bodies of type alias declarations already use the new prefixes,
23561
- so the results of the alias expansion will also use
23562
- the new prefixes consistently.%
23575
+ The transformation also does not change identifiers denoting type variables,
23576
+ There is no need to change those identifiers, because
23577
+ no occurrence of such an identifier resolves to a declaration in a
23578
+ different library.%
23579
+ %% TODO(eernst): Sort out the treatment of private identifiers, too.
23563
23580
}
23564
23581
23565
23582
\LMHash{}%
23566
- Every \synt{type} and type literal in the resulting program
23567
- is now expressed in a globally unique syntactic form.
23568
-
23569
- \rationale{%
23570
- This means that two terms denoting a type will have the same syntactic form
23571
- if and only if they denote the same type.
23572
- }
23583
+ Every \synt{type} and type literal in the resulting set of libraries
23584
+ is now expressed in a globally unique syntactic form,
23585
+ which is the form that we call the
23586
+ \IndexCustom{canonical syntax of}{type!canonical syntax of}
23587
+ said types.
23573
23588
23574
23589
\LMHash{}%
23575
23590
When we say that two types $T_1$ and $T_2$ have the
@@ -23579,6 +23594,36 @@ \subsubsection{The Canonical Syntax of Types}
23579
23594
have been transformed as described above,
23580
23595
and the resulting canonical syntaxes are identical.
23581
23596
23597
+ \rationale{%
23598
+ The transformation described here would not be useful in practice
23599
+ (or even possible---we can't edit \code{dart:core}).
23600
+ It only serves to show that we can express types using a syntactic form
23601
+ which is independent of the location.
23602
+ This is in turn needed in order to ensure that operations are well-defined
23603
+ even when they bring syntactic elements from different locations together,
23604
+ such as computations of subtype relationships,
23605
+ and construction of standard upper or lower bounds.
23606
+
23607
+ We could just as well have replaced the concrete syntax by a semantic
23608
+ notion of types,
23609
+ where each entity that denotes a type would be, in some sense,
23610
+ a reference to a specific declaration
23611
+ (this is likely to be the approach used by tool implementations).
23612
+ However, that approach would be somewhat inconvenient in a specification,
23613
+ because we would need to re-build all the structures that the
23614
+ syntax offers.
23615
+ For instance, we would need to support the construction of
23616
+ a semantic type entity for \code{Map<int, String>},
23617
+ based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
23618
+ and we would need to support deconstruction of those entities
23619
+ in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
23620
+ This would give rise to a lot of mechanism that will simply duplicate
23621
+ the structure of the syntax.
23622
+ So we prefer to show that the syntax \emph{can} be location independent,
23623
+ and that's sufficient to make syntax usable as our representation of
23624
+ static semantic types.%
23625
+ }
23626
+
23582
23627
23583
23628
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23584
23629
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -26302,7 +26347,7 @@ \section*{Appendix: Algorithmic Subtyping}
26302
26347
\item
26303
26348
\textbf{Reflexivity:}
26304
26349
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
26305
-
26350
+
26306
26351
\commentary{%
26307
26352
Note that this check is necessary as the base case for primitive types,
26308
26353
and type variables, but not for composite types.
@@ -26318,7 +26363,7 @@ \section*{Appendix: Algorithmic Subtyping}
26318
26363
\item
26319
26364
\textbf{Left Top:}
26320
26365
if $T_0$ is \DYNAMIC{} or \VOID{}
26321
- then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
26366
+ then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
26322
26367
\item
26323
26368
\textbf{Left Bottom:}
26324
26369
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -26354,8 +26399,7 @@ \section*{Appendix: Algorithmic Subtyping}
26354
26399
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
26355
26400
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
26356
26401
\item
26357
- if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
26358
- then the query is true.
26402
+ if $T_1$ is \code{$S$?} for some $S$ then the query is true.
26359
26403
\item
26360
26404
Otherwise, the query is false.
26361
26405
\end{itemize}
@@ -26398,7 +26442,7 @@ \section*{Appendix: Algorithmic Subtyping}
26398
26442
\begin{itemize}
26399
26443
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
26400
26444
\item or \SubtypeNE{T_0}{S_1}.
26401
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26445
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26402
26446
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26403
26447
\end{itemize}
26404
26448
\item
@@ -26408,7 +26452,7 @@ \section*{Appendix: Algorithmic Subtyping}
26408
26452
\begin{itemize}
26409
26453
\item either \SubtypeNE{T_0}{S_1}.
26410
26454
\item or \SubtypeNE{T_0}{\code{Null}}.
26411
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26455
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26412
26456
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26413
26457
\end{itemize}
26414
26458
\item
@@ -26446,7 +26490,10 @@ \section*{Appendix: Algorithmic Subtyping}
26446
26490
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
26447
26491
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
26448
26492
26449
- where each of the following hold:
26493
+ such that each of the following criteria is satisfied,
26494
+ where the $Z_i$ are fresh type variables with bounds
26495
+ $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
26496
+
26450
26497
\begin{itemize}
26451
26498
\item $p \geq n$.
26452
26499
\item $m \geq q$.
@@ -26455,8 +26502,6 @@ \section*{Appendix: Algorithmic Subtyping}
26455
26502
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
26456
26503
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
26457
26504
have the same canonical syntax, for $i \in 0 .. k$.
26458
- \item where the $Z_i$ are fresh type variables with bounds
26459
- $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
26460
26505
\end{itemize}
26461
26506
\item
26462
26507
\textbf{Named Function Types:}
@@ -26466,7 +26511,7 @@ \section*{Appendix: Algorithmic Subtyping}
26466
26511
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
26467
26512
$X_k$\,\EXTENDS\,$B_{0k}$>(%
26468
26513
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
26469
- \{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26514
+ \{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26470
26515
26471
26516
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
26472
26517
and $T_1$ is
@@ -26475,7 +26520,7 @@ \section*{Appendix: Algorithmic Subtyping}
26475
26520
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
26476
26521
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
26477
26522
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
26478
- \{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26523
+ \{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26479
26524
26480
26525
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
26481
26526
and the following criteria are all satisfied,
0 commit comments