Skip to content

Commit 2e37a22

Browse files
committed
Improved canonical syntax text, did small fixes in algorithmic subtyping
1 parent 2ec7325 commit 2e37a22

File tree

1 file changed

+95
-50
lines changed

1 file changed

+95
-50
lines changed

specification/dartLangSpec.tex

Lines changed: 95 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -22967,12 +22967,13 @@ \subsubsection{The Canonical Syntax of Types}
2296722967
\rationale{%
2296822968
This shows that concrete syntax behaves in such a manner that it is
2296922969
unsafe to consider two types as the same type,
22970-
based on the fact that they are denoted by the same syntax.
22970+
based on the fact that they are denoted by the same syntax,
22971+
even during the static analysis of a single expression.
2297122972

2297222973
Similarly, it is incorrect to consider two terms derived from \synt{type}
22973-
as different types based on the fact that they are syntactically different,
22974-
as they could in fact be the same type,
22975-
e.g., imported with different import prefixes.%
22974+
as different types based on the fact that they are syntactically different.
22975+
They could in fact be the same type,
22976+
e.g., imported with different import prefixes.
2297622977

2297722978
Consequently, we introduce the notion of the canonical syntax for a type,
2297822979
which has the property that each type has a unique syntactic form.
@@ -22988,49 +22989,63 @@ \subsubsection{The Canonical Syntax of Types}
2298822989
of the types in a given library $L_1$
2298922990
and all libraries \List{L}{2}{n} reachable from $L_1$ via
2299022991
one or more import links,
22991-
first choose a set of distinct fresh identifiers
22992+
first choose a set of distinct, globally fresh identifiers
2299222993
\List{\metavar{prefix}}{1}{n}.
22993-
Then transform each library $L_i$, $i \in 1 .. n$,
22994-
such that $L_i$ imports itself with the prefix $\metavar{prefix}_i$,
22995-
and $L_i$ imports \code{dart:core} explicitly
22996-
with the suitable prefix $\metavar{prefix}_j$ for some $j$,
22997-
and change all existing imports to use the prefix
22998-
corresponding to the library which is being imported.
22994+
Then transform each library $L_i$, $i \in 1 .. n$ as follows:
2299922995

23000-
\LMHash{}%
23001-
Next, transform every identifier expression and every \synt{typeName}
23002-
that refers to an imported declaration or a library declaration
23003-
such that it uses the prefix $\metavar{prefix}_j$ with the relevant $j$,
23004-
and such that every name resolves to the same declaration
23005-
as it did in the original program.
22996+
\begin{enumerate}
22997+
\item
22998+
Add a set of import directives to $L_i$ that imports
22999+
each of the libraries \List{L}{1}{n} with
23000+
the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23001+
23002+
\commentary{%
23003+
This means that every library in the set
23004+
$\{\,\List{L}{1}{n}\,\}$
23005+
imports every other library in that set,
23006+
even itself and system libraries like \code{dart:core}.%
23007+
}
23008+
\item
23009+
Let \id{} be a non-private identifier that resolves to
23010+
a library declaration in the library $L_j$ in the original program;
23011+
\id{} is transformed to \code{$\metavar{prefix}_j$.\id}.
23012+
Let \code{$p$.\id} be a qualified identifier where $p$ is
23013+
an import prefix in the original program,
23014+
\id{} is a non-private identifier,
23015+
and \code{$p$.\id} resolves to
23016+
a library declaration in the library $L_j$ in the original program;
23017+
\code{$p$.\id} is transformed to \code{$\metavar{prefix}_j$.\id}.
23018+
\item
23019+
%% TODO(eernst): We should rename private names to fresh public names.
23020+
Replace every type that denotes a type alias
23021+
by its transitive alias expansion
23022+
(\ref{typedef}).
23023+
\commentary{%
23024+
Note that the bodies of type alias declarations
23025+
already use the new prefixes,
23026+
so the results of the alias expansion will also use
23027+
the new prefixes consistently.%
23028+
}
23029+
\end{enumerate}
2300623030

2300723031
\commentary{%
2300823032
Note that this transformation does not change any occurrence of \VOID;
23009-
\VOID{} is a reserved word
23010-
and \code{$\metavar{prefix}_j$.\VOID} is a syntax error.%
23011-
}
23033+
\VOID{} is a reserved word, not an identifier.
23034+
Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
2301223035

23013-
%% TODO(eernst), for review: Rename private names to fresh public names?
23014-
%% Otherwise the type alias could turn into a term containing private names
23015-
%% from different libraries.
23016-
\LMHash{}%
23017-
Finally, replace every type that denotes a type alias
23018-
by its transitive alias expansion
23019-
(\ref{typedef}).
23020-
\commentary{%
23021-
Note that the bodies of type alias declarations already use the new prefixes,
23022-
so the results of the alias expansion will also use
23023-
the new prefixes consistently.%
23036+
The transformation also does not change identifiers denoting type variables,
23037+
There is no need to change those identifiers, because
23038+
no occurrence of such an identifier resolves to a declaration in a
23039+
different library.%
23040+
%% TODO(eernst): Sort out the treatment of private identifiers, too.
2302423041
}
2302523042

2302623043
\LMHash{}%
23027-
Every \synt{type} and type literal in the resulting program
23028-
is now expressed in a globally unique syntactic form.
23029-
23030-
\rationale{%
23031-
This means that two terms denoting a type will have the same syntactic form
23032-
if and only if they denote the same type.
23033-
}
23044+
Every \synt{type} and type literal in the resulting set of libraries
23045+
is now expressed in a globally unique syntactic form,
23046+
which is the form that we call the
23047+
\IndexCustom{canonical syntax of}{type!canonical syntax of}
23048+
said types.
2303423049

2303523050
\LMHash{}%
2303623051
When we say that two types $T_1$ and $T_2$ have the
@@ -23040,6 +23055,36 @@ \subsubsection{The Canonical Syntax of Types}
2304023055
have been transformed as described above,
2304123056
and the resulting canonical syntaxes are identical.
2304223057

23058+
\rationale{%
23059+
The transformation described here would not be useful in practice
23060+
(or even possible---we can't edit \code{dart:core}).
23061+
It only serves to show that we can express types using a syntactic form
23062+
which is independent of the location.
23063+
This is in turn needed in order to ensure that operations are well-defined
23064+
even when they bring syntactic elements from different locations together,
23065+
such as computations of subtype relationships,
23066+
and construction of standard upper or lower bounds.
23067+
23068+
We could just as well have replaced the concrete syntax by a semantic
23069+
notion of types,
23070+
where each entity that denotes a type would be, in some sense,
23071+
a reference to a specific declaration
23072+
(this is likely to be the approach used by tool implementations).
23073+
However, that approach would be somewhat inconvenient in a specification,
23074+
because we would need to re-build all the structures that the
23075+
syntax offers.
23076+
For instance, we would need to support the construction of
23077+
a semantic type entity for \code{Map<int, String>},
23078+
based on the semantic type entity for \code{int}, \code{String}, and \code{Map},
23079+
and we would need to support deconstruction of those entities
23080+
in order to prove things like \SubtypeNE{Never}{\code{Map<int, String>}}.
23081+
This would give rise to a lot of mechanism that will simply duplicate
23082+
the structure of the syntax.
23083+
So we prefer to show that the syntax \emph{can} be location independent,
23084+
and that's sufficient to make syntax usable as our representation of
23085+
static semantic types.%
23086+
}
23087+
2304323088

2304423089
\subsubsection{Standard Upper Bounds and Standard Lower Bounds}
2304523090
\LMLabel{standardUpperBoundsAndStandardLowerBounds}
@@ -25762,7 +25807,7 @@ \section*{Appendix: Algorithmic Subtyping}
2576225807
\item
2576325808
\textbf{Reflexivity:}
2576425809
if $T_0$ and $T_1$ are the same type then \SubtypeNE{T_0}{T_1}
25765-
25810+
2576625811
\commentary{%
2576725812
Note that this check is necessary as the base case for primitive types,
2576825813
and type variables, but not for composite types.
@@ -25778,7 +25823,7 @@ \section*{Appendix: Algorithmic Subtyping}
2577825823
\item
2577925824
\textbf{Left Top:}
2578025825
if $T_0$ is \DYNAMIC{} or \VOID{}
25781-
then \SubtypeNE{T_0}{T_1} if \SubtypeNE{\code{Object?}}{T_1}.
25826+
then \SubtypeNE{T_0}{T_1} if{}f \SubtypeNE{\code{Object?}}{T_1}.
2578225827
\item
2578325828
\textbf{Left Bottom:}
2578425829
if $T_0$ is \code{Never} then \SubtypeNE{T_0}{T_1}.
@@ -25814,8 +25859,7 @@ \section*{Appendix: Algorithmic Subtyping}
2581425859
if $T_1$ is \code{FutureOr<$S$>} for some $S$,
2581525860
then the query is true if{}f \SubtypeNE{\code{Null}}{S}.
2581625861
\item
25817-
if $T_1$ is \code{Null} or \code{$S$?} for some $S$,
25818-
then the query is true.
25862+
if $T_1$ is \code{$S$?} for some $S$ then the query is true.
2581925863
\item
2582025864
Otherwise, the query is false.
2582125865
\end{itemize}
@@ -25833,7 +25877,7 @@ \section*{Appendix: Algorithmic Subtyping}
2583325877
if $T_0$ is a type variable $X_0$
2583425878
or a promoted type variables \code{$X_0$\,\&\,$S_0$} and $T_1$ is $X_0$
2583525879
then \SubtypeNE{T_0}{T_1}.
25836-
25880+
2583725881
\commentary{
2583825882
Note that this rule is admissible, and can be safely elided if desired.%
2583925883
}
@@ -25858,7 +25902,7 @@ \section*{Appendix: Algorithmic Subtyping}
2585825902
\begin{itemize}
2585925903
\item either \SubtypeNE{T_0}{\code{Future<$S_1$>}}.
2586025904
\item or \SubtypeNE{T_0}{S_1}.
25861-
\item or $T_0$ is $X_0$ and $X_0$ has bound $S_0$ and \SubtypeNE{S_0}{T_1}.
25905+
\item or $T_0$ is $X_0$ and $X_0$ has bound $B_0$ and \SubtypeNE{B_0}{T_1}.
2586225906
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
2586325907
\end{itemize}
2586425908
\item
@@ -25868,7 +25912,7 @@ \section*{Appendix: Algorithmic Subtyping}
2586825912
\begin{itemize}
2586925913
\item either \SubtypeNE{T_0}{S_1}.
2587025914
\item or \SubtypeNE{T_0}{\code{Null}}.
25871-
\item or $T_0$ is $X_0$ and $X_0$ has bound $S_0$ and \SubtypeNE{S_0}{T_1}.
25915+
\item or $T_0$ is $X_0$ and $X_0$ has bound $B_0$ and \SubtypeNE{B_0}{T_1}.
2587225916
\item or $T_0$ is \code{$X_0$\,\&\,$S_0$} and \SubtypeNE{S_0}{T_1}.
2587325917
\end{itemize}
2587425918
\item
@@ -25906,7 +25950,10 @@ \section*{Appendix: Algorithmic Subtyping}
2590625950
$S_0$\,$y_0$, \ldots, $S_p$\,$y_p$, %
2590725951
[$S_{p+1}$\,$y_{p+1}$, \ldots, $S_q$\,$y_q$])}
2590825952

25909-
where each of the following hold:
25953+
such that each of the following criteria is satisfied,
25954+
where the $Z_i$ are fresh type variables with bounds
25955+
$B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$:
25956+
2591025957
\begin{itemize}
2591125958
\item $p \geq n$.
2591225959
\item $m \geq q$.
@@ -25915,8 +25962,6 @@ \section*{Appendix: Algorithmic Subtyping}
2591525962
\item \SubtypeNE{U_0[Z_0/X_0, \ldots, Z_k/X_k]}{U_1[Z_0/Y_0, \ldots, Z_k/Y_k]}.
2591625963
\item $B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$ and $B_{1i}[Z_0/Y_0, \ldots, Z_k/Y_k]$
2591725964
have the same canonical syntax, for $i \in 0 .. k$.
25918-
\item where the $Z_i$ are fresh type variables with bounds
25919-
$B_{0i}[Z_0/X_0, \ldots, Z_k/X_k]$.
2592025965
\end{itemize}
2592125966
\item
2592225967
\textbf{Named Function Types:}
@@ -25926,7 +25971,7 @@ \section*{Appendix: Algorithmic Subtyping}
2592625971
$U_0$ \FUNCTION<$X_0$\,\EXTENDS\,$B_{00}$, \ldots, %
2592725972
$X_k$\,\EXTENDS\,$B_{0k}$>(%
2592825973
$V_0$\,$x_0$, \ldots, $V_n$\,$x_n$, %
25929-
\{ $r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
25974+
\{$r_{0,n+1}$\,$V_{n+1}$\,$x_{n+1}$, \ldots, $r_{0m}$\,$V_m$\,$x_m$\})}
2593025975

2593125976
where $r_{0j}$ is empty or \REQUIRED{} for $j \in n+1 .. m$
2593225977
and $T_1$ is
@@ -25935,7 +25980,7 @@ \section*{Appendix: Algorithmic Subtyping}
2593525980
$U_1$ \FUNCTION<$Y_0$\,\EXTENDS\,$B_{10}$, \ldots, %
2593625981
$Y_k$\,\EXTENDS\,$B_{1k}$>(%
2593725982
$S_0$\,$y_0$, \ldots, $S_n$\,$y_n$, %
25938-
\{ $r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
25983+
\{$r_{1,n+1}$\,$S_{n+1}$\,$y_{n+1}$, \ldots, $r_{1q}$\,$S_q$\,$y_q$\})}
2593925984

2594025985
where $r_{1j}$ is empty or \REQUIRED{} for $j \in n+1 .. q$
2594125986
and the following criteria are all satisfied,

0 commit comments

Comments
 (0)