@@ -23486,12 +23486,13 @@ \subsubsection{The Canonical Syntax of Types}
23486
23486
\rationale{%
23487
23487
This shows that concrete syntax behaves in such a manner that it is
23488
23488
unsafe to consider two types as the same type,
23489
- based on the fact that they are denoted by the same syntax.
23489
+ based on the fact that they are denoted by the same syntax,
23490
+ even during the static analysis of a single expression.
23490
23491
23491
23492
Similarly, it is incorrect to consider two terms derived from \synt{type}
23492
- as different types based on the fact that they are syntactically different,
23493
- as they could in fact be the same type,
23494
- e.g., imported with different import prefixes.%
23493
+ as different types based on the fact that they are syntactically different.
23494
+ They could in fact be the same type,
23495
+ e.g., imported with different import prefixes.
23495
23496
23496
23497
Consequently, we introduce the notion of the canonical syntax for a type,
23497
23498
which has the property that each type has a unique syntactic form.
@@ -23507,49 +23508,63 @@ \subsubsection{The Canonical Syntax of Types}
23507
23508
of the types in a given library $L_1$
23508
23509
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23509
23510
one or more import links,
23510
- first choose a set of distinct fresh identifiers
23511
+ first choose a set of distinct, globally fresh identifiers
23511
23512
\List{\metavar{prefix}}{1}{n}.
23512
- Then transform each library $L_i$, $i \in 1 .. n$,
23513
- such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
23514
- and $L_i$ imports \code{dart:core} explicitly
23515
- with the suitable prefix $\metavar{prefix}_j$ for some $j$,
23516
- and change all existing imports to use the prefix
23517
- corresponding to the library which is being imported.
23513
+ Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23518
23514
23519
- \LMHash{}%
23520
- Next, transform every identifier expression and every \synt{typeName}
23521
- that refers to an imported declaration or a library declaration
23522
- such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23523
- and such that every name resolves to the same declaration
23524
- as it did in the original program.
23515
+ \begin{enumerate}
23516
+ \item
23517
+ Add a set of import directives to $L_i$ that imports
23518
+ each of the libraries \List{L}{1}{n} with
23519
+ the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23520
+
23521
+ \commentary{%
23522
+ This means that every library in the set
23523
+ $\{\,\List{L}{1}{n}\,\}$
23524
+ imports every other library in that set,
23525
+ even itself and system libraries like \code{dart:core}.%
23526
+ }
23527
+ \item
23528
+ Let \id{} be a non-private identifier that resolves to
23529
+ a library declaration in the library $L_j$ in the original program;
23530
+ \id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23531
+ Let \code{$p$.\id} be a qualified identifier where $p$ is
23532
+ an import prefix in the original program,
23533
+ \id{} is a non-private identifier,
23534
+ and \code{$p$.\id} resolves to
23535
+ a library declaration in the library $L_j$ in the original program;
23536
+ \code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23537
+ \item
23538
+ %% TODO(eernst): We should rename private names to fresh public names.
23539
+ Replace every type that denotes a type alias
23540
+ by its transitive alias expansion
23541
+ (\ref{typedef}).
23542
+ \commentary{%
23543
+ Note that the bodies of type alias declarations
23544
+ already use the new prefixes,
23545
+ so the results of the alias expansion will also use
23546
+ the new prefixes consistently.%
23547
+ }
23548
+ \end{enumerate}
23525
23549
23526
23550
\commentary{%
23527
23551
Note that this transformation does not change any occurrence of \VOID;
23528
- \VOID{} is a reserved word
23529
- and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23530
- }
23552
+ \VOID{} is a reserved word, not an identifier.
23553
+ Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23531
23554
23532
- %% TODO(eernst), for review: Rename private names to fresh public names?
23533
- %% Otherwise the type alias could turn into a term containing private names
23534
- %% from different libraries.
23535
- \LMHash{}%
23536
- Finally, replace every type that denotes a type alias
23537
- by its transitive alias expansion
23538
- (\ref{typedef}).
23539
- \commentary{%
23540
- Note that the bodies of type alias declarations already use the new prefixes,
23541
- so the results of the alias expansion will also use
23542
- the new prefixes consistently.%
23555
+ The transformation also does not change identifiers denoting type variables,
23556
+ There is no need to change those identifiers, because
23557
+ no occurrence of such an identifier resolves to a declaration in a
23558
+ different library.%
23559
+ %% TODO(eernst): Sort out the treatment of private identifiers, too.
23543
23560
}
23544
23561
23545
23562
\LMHash{}%
23546
- Every \synt{type} and type literal in the resulting program
23547
- is now expressed in a globally unique syntactic form.
23548
-
23549
- \rationale{%
23550
- This means that two terms denoting a type will have the same syntactic form
23551
- if and only if they denote the same type.
23552
- }
23563
+ Every \synt{type} and type literal in the resulting set of libraries
23564
+ is now expressed in a globally unique syntactic form,
23565
+ which is the form that we call the
23566
+ \IndexCustom{canonical syntax of}{type!canonical syntax of}
23567
+ said types.
23553
23568
23554
23569
\LMHash{}%
23555
23570
When we say that two types $T_1$ and $T_2$ have the
@@ -23559,6 +23574,36 @@ \subsubsection{The Canonical Syntax of Types}
23559
23574
have been transformed as described above,
23560
23575
and the resulting canonical syntaxes are identical.
23561
23576
23577
+ \rationale{%
23578
+ The transformation described here would not be useful in practice
23579
+ (or even possible---we can't edit \code{dart:core}).
23580
+ It only serves to show that we can express types using a syntactic form
23581
+ which is independent of the location.
23582
+ This is in turn needed in order to ensure that operations are well-defined
23583
+ even when they bring syntactic elements from different locations together,
23584
+ such as computations of subtype relationships,
23585
+ and construction of standard upper or lower bounds.
23586
+
23587
+ We could just as well have replaced the concrete syntax by a semantic
23588
+ notion of types,
23589
+ where each entity that denotes a type would be, in some sense,
23590
+ a reference to a specific declaration
23591
+ (this is likely to be the approach used by tool implementations).
23592
+ However, that approach would be somewhat inconvenient in a specification,
23593
+ because we would need to re-build all the structures that the
23594
+ syntax offers.
23595
+ For instance, we would need to support the construction of
23596
+ a semantic type entity for \code{Map<int, String>},
23597
+ based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
23598
+ and we would need to support deconstruction of those entities
23599
+ in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
23600
+ This would give rise to a lot of mechanism that will simply duplicate
23601
+ the structure of the syntax.
23602
+ So we prefer to show that the syntax \emph{can} be location independent,
23603
+ and that's sufficient to make syntax usable as our representation of
23604
+ static semantic types.%
23605
+ }
23606
+
23562
23607
23563
23608
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23564
23609
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -26282,7 +26327,7 @@ \section*{Appendix: Algorithmic Subtyping}
26282
26327
\item
26283
26328
\textbf{Reflexivity:}
26284
26329
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
26285
-
26330
+
26286
26331
\commentary{%
26287
26332
Note that this check is necessary as the base case for primitive types,
26288
26333
and type variables, but not for composite types.
@@ -26298,7 +26343,7 @@ \section*{Appendix: Algorithmic Subtyping}
26298
26343
\item
26299
26344
\textbf{Left Top:}
26300
26345
if $T_0$ is \DYNAMIC{} or \VOID{}
26301
- then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
26346
+ then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
26302
26347
\item
26303
26348
\textbf{Left Bottom:}
26304
26349
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -26334,8 +26379,7 @@ \section*{Appendix: Algorithmic Subtyping}
26334
26379
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
26335
26380
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
26336
26381
\item
26337
- if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
26338
- then the query is true.
26382
+ if $T_1$ is \code{$S$?} for some $S$ then the query is true.
26339
26383
\item
26340
26384
Otherwise, the query is false.
26341
26385
\end{itemize}
@@ -26378,7 +26422,7 @@ \section*{Appendix: Algorithmic Subtyping}
26378
26422
\begin{itemize}
26379
26423
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
26380
26424
\item or \SubtypeNE{T_0}{S_1}.
26381
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26425
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26382
26426
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26383
26427
\end{itemize}
26384
26428
\item
@@ -26388,7 +26432,7 @@ \section*{Appendix: Algorithmic Subtyping}
26388
26432
\begin{itemize}
26389
26433
\item either \SubtypeNE{T_0}{S_1}.
26390
26434
\item or \SubtypeNE{T_0}{\code{Null}}.
26391
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26435
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
26392
26436
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
26393
26437
\end{itemize}
26394
26438
\item
@@ -26426,7 +26470,10 @@ \section*{Appendix: Algorithmic Subtyping}
26426
26470
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
26427
26471
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
26428
26472
26429
- where each of the following hold:
26473
+ such that each of the following criteria is satisfied,
26474
+ where the $Z_i$ are fresh type variables with bounds
26475
+ $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
26476
+
26430
26477
\begin{itemize}
26431
26478
\item $p \geq n$.
26432
26479
\item $m \geq q$.
@@ -26435,8 +26482,6 @@ \section*{Appendix: Algorithmic Subtyping}
26435
26482
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
26436
26483
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
26437
26484
have the same canonical syntax, for $i \in 0 .. k$.
26438
- \item where the $Z_i$ are fresh type variables with bounds
26439
- $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
26440
26485
\end{itemize}
26441
26486
\item
26442
26487
\textbf{Named Function Types:}
@@ -26446,7 +26491,7 @@ \section*{Appendix: Algorithmic Subtyping}
26446
26491
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
26447
26492
$X_k$\,\EXTENDS\,$B_{0k}$>(%
26448
26493
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
26449
- \{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26494
+ \{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26450
26495
26451
26496
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
26452
26497
and $T_1$ is
@@ -26455,7 +26500,7 @@ \section*{Appendix: Algorithmic Subtyping}
26455
26500
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
26456
26501
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
26457
26502
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
26458
- \{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26503
+ \{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26459
26504
26460
26505
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
26461
26506
and the following criteria are all satisfied,
0 commit comments