@@ -23058,12 +23058,13 @@ \subsubsection{The Canonical Syntax of Types}
23058
23058
\rationale{%
23059
23059
This shows that concrete syntax behaves in such a manner that it is
23060
23060
unsafe to consider two types as the same type,
23061
- based on the fact that they are denoted by the same syntax.
23061
+ based on the fact that they are denoted by the same syntax,
23062
+ even during the static analysis of a single expression.
23062
23063
23063
23064
Similarly, it is incorrect to consider two terms derived from \synt{type}
23064
- as different types based on the fact that they are syntactically different,
23065
- as they could in fact be the same type,
23066
- e.g., imported with different import prefixes.%
23065
+ as different types based on the fact that they are syntactically different.
23066
+ They could in fact be the same type,
23067
+ e.g., imported with different import prefixes.
23067
23068
23068
23069
Consequently, we introduce the notion of the canonical syntax for a type,
23069
23070
which has the property that each type has a unique syntactic form.
@@ -23079,49 +23080,63 @@ \subsubsection{The Canonical Syntax of Types}
23079
23080
of the types in a given library $L_1$
23080
23081
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23081
23082
one or more import links,
23082
- first choose a set of distinct fresh identifiers
23083
+ first choose a set of distinct, globally fresh identifiers
23083
23084
\List{\metavar{prefix}}{1}{n}.
23084
- Then transform each library $L_i$, $i \in 1 .. n$,
23085
- such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
23086
- and $L_i$ imports \code{dart:core} explicitly
23087
- with the suitable prefix $\metavar{prefix}_j$ for some $j$,
23088
- and change all existing imports to use the prefix
23089
- corresponding to the library which is being imported.
23085
+ Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23090
23086
23091
- \LMHash{}%
23092
- Next, transform every identifier expression and every \synt{typeName}
23093
- that refers to an imported declaration or a library declaration
23094
- such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23095
- and such that every name resolves to the same declaration
23096
- as it did in the original program.
23087
+ \begin{enumerate}
23088
+ \item
23089
+ Add a set of import directives to $L_i$ that imports
23090
+ each of the libraries \List{L}{1}{n} with
23091
+ the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23092
+
23093
+ \commentary{%
23094
+ This means that every library in the set
23095
+ $\{\,\List{L}{1}{n}\,\}$
23096
+ imports every other library in that set,
23097
+ even itself and system libraries like \code{dart:core}.%
23098
+ }
23099
+ \item
23100
+ Let \id{} be a non-private identifier that resolves to
23101
+ a library declaration in the library $L_j$ in the original program;
23102
+ \id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23103
+ Let \code{$p$.\id} be a qualified identifier where $p$ is
23104
+ an import prefix in the original program,
23105
+ \id{} is a non-private identifier,
23106
+ and \code{$p$.\id} resolves to
23107
+ a library declaration in the library $L_j$ in the original program;
23108
+ \code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23109
+ \item
23110
+ %% TODO(eernst): We should rename private names to fresh public names.
23111
+ Replace every type that denotes a type alias
23112
+ by its transitive alias expansion
23113
+ (\ref{typedef}).
23114
+ \commentary{%
23115
+ Note that the bodies of type alias declarations
23116
+ already use the new prefixes,
23117
+ so the results of the alias expansion will also use
23118
+ the new prefixes consistently.%
23119
+ }
23120
+ \end{enumerate}
23097
23121
23098
23122
\commentary{%
23099
23123
Note that this transformation does not change any occurrence of \VOID;
23100
- \VOID{} is a reserved word
23101
- and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23102
- }
23124
+ \VOID{} is a reserved word, not an identifier.
23125
+ Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23103
23126
23104
- %% TODO(eernst), for review: Rename private names to fresh public names?
23105
- %% Otherwise the type alias could turn into a term containing private names
23106
- %% from different libraries.
23107
- \LMHash{}%
23108
- Finally, replace every type that denotes a type alias
23109
- by its transitive alias expansion
23110
- (\ref{typedef}).
23111
- \commentary{%
23112
- Note that the bodies of type alias declarations already use the new prefixes,
23113
- so the results of the alias expansion will also use
23114
- the new prefixes consistently.%
23127
+ The transformation also does not change identifiers denoting type variables,
23128
+ There is no need to change those identifiers, because
23129
+ no occurrence of such an identifier resolves to a declaration in a
23130
+ different library.%
23131
+ %% TODO(eernst): Sort out the treatment of private identifiers, too.
23115
23132
}
23116
23133
23117
23134
\LMHash{}%
23118
- Every \synt{type} and type literal in the resulting program
23119
- is now expressed in a globally unique syntactic form.
23120
-
23121
- \rationale{%
23122
- This means that two terms denoting a type will have the same syntactic form
23123
- if and only if they denote the same type.
23124
- }
23135
+ Every \synt{type} and type literal in the resulting set of libraries
23136
+ is now expressed in a globally unique syntactic form,
23137
+ which is the form that we call the
23138
+ \IndexCustom{canonical syntax of}{type!canonical syntax of}
23139
+ said types.
23125
23140
23126
23141
\LMHash{}%
23127
23142
When we say that two types $T_1$ and $T_2$ have the
@@ -23131,6 +23146,36 @@ \subsubsection{The Canonical Syntax of Types}
23131
23146
have been transformed as described above,
23132
23147
and the resulting canonical syntaxes are identical.
23133
23148
23149
+ \rationale{%
23150
+ The transformation described here would not be useful in practice
23151
+ (or even possible---we can't edit \code{dart:core}).
23152
+ It only serves to show that we can express types using a syntactic form
23153
+ which is independent of the location.
23154
+ This is in turn needed in order to ensure that operations are well-defined
23155
+ even when they bring syntactic elements from different locations together,
23156
+ such as computations of subtype relationships,
23157
+ and construction of standard upper or lower bounds.
23158
+
23159
+ We could just as well have replaced the concrete syntax by a semantic
23160
+ notion of types,
23161
+ where each entity that denotes a type would be, in some sense,
23162
+ a reference to a specific declaration
23163
+ (this is likely to be the approach used by tool implementations).
23164
+ However, that approach would be somewhat inconvenient in a specification,
23165
+ because we would need to re-build all the structures that the
23166
+ syntax offers.
23167
+ For instance, we would need to support the construction of
23168
+ a semantic type entity for \code{Map<int, String>},
23169
+ based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
23170
+ and we would need to support deconstruction of those entities
23171
+ in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
23172
+ This would give rise to a lot of mechanism that will simply duplicate
23173
+ the structure of the syntax.
23174
+ So we prefer to show that the syntax \emph{can} be location independent,
23175
+ and that's sufficient to make syntax usable as our representation of
23176
+ static semantic types.%
23177
+ }
23178
+
23134
23179
23135
23180
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
23136
23181
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -25853,7 +25898,7 @@ \section*{Appendix: Algorithmic Subtyping}
25853
25898
\item
25854
25899
\textbf{Reflexivity:}
25855
25900
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
25856
-
25901
+
25857
25902
\commentary{%
25858
25903
Note that this check is necessary as the base case for primitive types,
25859
25904
and type variables, but not for composite types.
@@ -25869,7 +25914,7 @@ \section*{Appendix: Algorithmic Subtyping}
25869
25914
\item
25870
25915
\textbf{Left Top:}
25871
25916
if $T_0$ is \DYNAMIC{} or \VOID{}
25872
- then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
25917
+ then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
25873
25918
\item
25874
25919
\textbf{Left Bottom:}
25875
25920
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -25905,8 +25950,7 @@ \section*{Appendix: Algorithmic Subtyping}
25905
25950
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
25906
25951
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
25907
25952
\item
25908
- if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
25909
- then the query is true.
25953
+ if $T_1$ is \code{$S$?} for some $S$ then the query is true.
25910
25954
\item
25911
25955
Otherwise, the query is false.
25912
25956
\end{itemize}
@@ -25949,7 +25993,7 @@ \section*{Appendix: Algorithmic Subtyping}
25949
25993
\begin{itemize}
25950
25994
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
25951
25995
\item or \SubtypeNE{T_0}{S_1}.
25952
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
25996
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
25953
25997
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
25954
25998
\end{itemize}
25955
25999
\item
@@ -25959,7 +26003,7 @@ \section*{Appendix: Algorithmic Subtyping}
25959
26003
\begin{itemize}
25960
26004
\item either \SubtypeNE{T_0}{S_1}.
25961
26005
\item or \SubtypeNE{T_0}{\code{Null}}.
25962
- \item or $T_0$ is $X_0$ and $X_0$ has bound $S_0 $ and \SubtypeNE{S_0 }{T_1}.
26006
+ \item or $T_0$ is $X_0$ and $X_0$ has bound $B_0 $ and \SubtypeNE{B_0 }{T_1}.
25963
26007
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
25964
26008
\end{itemize}
25965
26009
\item
@@ -25997,7 +26041,10 @@ \section*{Appendix: Algorithmic Subtyping}
25997
26041
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
25998
26042
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
25999
26043
26000
- where each of the following hold:
26044
+ such that each of the following criteria is satisfied,
26045
+ where the $Z_i$ are fresh type variables with bounds
26046
+ $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
26047
+
26001
26048
\begin{itemize}
26002
26049
\item $p \geq n$.
26003
26050
\item $m \geq q$.
@@ -26006,8 +26053,6 @@ \section*{Appendix: Algorithmic Subtyping}
26006
26053
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
26007
26054
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
26008
26055
have the same canonical syntax, for $i \in 0 .. k$.
26009
- \item where the $Z_i$ are fresh type variables with bounds
26010
- $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
26011
26056
\end{itemize}
26012
26057
\item
26013
26058
\textbf{Named Function Types:}
@@ -26017,7 +26062,7 @@ \section*{Appendix: Algorithmic Subtyping}
26017
26062
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
26018
26063
$X_k$\,\EXTENDS\,$B_{0k}$>(%
26019
26064
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
26020
- \{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26065
+ \{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
26021
26066
26022
26067
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
26023
26068
and $T_1$ is
@@ -26026,7 +26071,7 @@ \section*{Appendix: Algorithmic Subtyping}
26026
26071
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
26027
26072
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
26028
26073
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
26029
- \{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26074
+ \{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
26030
26075
26031
26076
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
26032
26077
and the following criteria are all satisfied,
0 commit comments