Skip to content

Commit d0c774e

Browse files
committed
Added section about explicitly resolved (fka canonical) syntax
1 parent debe046 commit d0c774e

File tree

1 file changed

+215
-25
lines changed

1 file changed

+215
-25
lines changed

specification/dartLangSpec.tex

Lines changed: 215 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2675,7 +2675,7 @@ \subsection{Type of a Function}
26752675
different type parameters, F-bounds, and the types of formal parameters.
26762676
However, we do not wish to distinguish between two function types
26772677
if they have the same structure and only differ in the choice of names.
2678-
This treatment of names is also known as alpha-equivalence.%
2678+
This treatment of names is also known as alpha equivalence.%
26792679
}
26802680

26812681
\LMHash{}%
@@ -22015,24 +22015,18 @@ \subsubsection{Subtype Rules}
2201522015
However, we must eliminate the difficulties associated with
2201622016
different syntax denoting the same type,
2201722017
and different types denoted by the same syntax.
22018-
We do this by assuming that every type in the program has been expressed
22019-
in a manner where those situations never occur,
22020-
because each type is denoted by the same globally unique syntax everywhere.%
22018+
We do this by defining in detail what it means to be the same type
22019+
(\ref{sameStaticType}).%
2202122020
}
2202222021

2202322022
\LMHash{}%
2202422023
In section~\ref{subtypes} and its subsections,
2202522024
all designations of types are considered to be the same
22026-
if{}f they have the same canonical syntax
22027-
(\ref{theCanonicalSyntaxOfTypes}).
22025+
type if{}f they satisfy the criteria in
22026+
Section~\ref{sameStaticType}.
2202822027

22029-
\commentary{%
22030-
Note that the canonical syntax also implies
22031-
transitive expansion of all type aliases
22032-
(\ref{typedef}).
22033-
In other words, subtyping rules do not need to consider type aliases,
22034-
because all type aliases have been expanded.%
22035-
}
22028+
\LMHash{}%
22029+
The subtype rules assume that all type aliases have been transitively expanded.
2203622030

2203722031
\LMHash{}%
2203822032
Every \synt{typeName} used in a type mentioned
@@ -22418,19 +22412,13 @@ \subsection{Function Types}
2241822412
coincide in this case.%
2241922413
}
2242022414

22421-
\LMHash{}%
22422-
Two function types are considered equal if consistent renaming of type
22423-
parameters can make them identical.
22424-
2242522415
\commentary{%
22426-
A common way to say this is that we do not distinguish
22427-
function types which are alpha-equivalent.
22428-
For the subtyping rule below this means we can assume that
22429-
a suitable renaming has already taken place.
22430-
In cases where this is not possible
22431-
because the number of type parameters in the two types differ
22432-
or the bounds are different,
22433-
no subtype relationship exists.%
22416+
Two function types are the same type
22417+
if, roughly, consistent renaming of type
22418+
parameters can make them identical.
22419+
This is also known as alpha equivalence.
22420+
The detailed rules are described in
22421+
Section~\ref{sameStaticType}.%
2243422422
}
2243522423

2243622424
\LMHash{}%
@@ -23303,6 +23291,208 @@ \subsubsection{Least Upper Bounds}
2330323291
}
2330423292

2330523293

23294+
\subsection{Same Static Type}
23295+
\LMLabel{sameStaticType}
23296+
23297+
\LMHash{}%
23298+
This section specifies how to soundly determine whether or not two types
23299+
that are encountered during static analysis are the same type.
23300+
23301+
\LMHash{}%
23302+
Concrete syntax denoting types gives rise to several difficulties
23303+
when used to determine static semantic properties,
23304+
like subtyping relationships
23305+
(\ref{subtypes})
23306+
or upper and lower bounds
23307+
(\ref{standardUpperBoundsAndStandardLowerBounds}).
23308+
23309+
\commentary{%
23310+
Note that the notion of being the same type at run time is different from
23311+
the notion of being the same type during static analysis.
23312+
For example, two distinct type variables \code{X} and \code{Y}
23313+
might at run time be bound to the same type, e.g.,
23314+
\code{List<int>}.
23315+
However, during static analysis we must maintain that
23316+
\code{X} and \code{Y} are different types
23317+
because there is no guarantee that they are always bound to
23318+
the same type at run time.%
23319+
}
23320+
23321+
\commentary{%
23322+
The phrases `same type' and `identical syntax' deserves some extra scrutiny.
23323+
If a library $L$ imports the libraries $L_1$ and $L_2$
23324+
(where $L_1$ and $L_2$ are not the same library),
23325+
and both $L_1$ and $L_2$ declare a class \code{C},
23326+
then the syntax \code{C} may occur as a type during static analysis of $L$
23327+
in situations where it refers to two distinct types.
23328+
23329+
For instance, $L_1$ could declare a variable \code{v}
23330+
of type \code{C}-in-$L_1$,
23331+
and $L_2$ could declare a function
23332+
\code{\VOID\,foo(C\,\,c)\,\,\{\}}
23333+
which uses the type \code{C}-in-$L_2$,
23334+
and $L$ could contain the expression \code{foo(v)}.
23335+
23336+
Note that even though it would be a compile-time error to use \code{C} in $L$
23337+
(because it is ambiguous),
23338+
it is not an error to have an expression like \code{foo(v)},
23339+
and the static analysis of this expression \emph{must}
23340+
be able to determine that the two types whose name is \code{C} are
23341+
not the same type. The invocation may or may not be an error,
23342+
depending on the subtyping relations.%
23343+
}
23344+
23345+
\rationale{%
23346+
This shows that concrete syntax behaves in such a manner that it is
23347+
unsafe to consider two types to be the same type,
23348+
based on the fact that they are denoted by the same syntax,
23349+
even during the static analysis of a single expression.
23350+
23351+
Similarly, it is incorrect to consider two terms derived from \synt{type}
23352+
as different types based on the fact that they are syntactically different.
23353+
For example, they could be the same type imported with different import
23354+
prefixes.
23355+
23356+
We could say that two identifiers
23357+
(possibly qualified, e.g., \code{myPrefix.C} and \code{C})
23358+
denote the same type
23359+
if they have been resolved to the same declaration.
23360+
23361+
However, we introduce \emph{the explicitly resolved syntax for a type},
23362+
which is basically an explicit representation of this idea,
23363+
in order to make the underlying issues more explicit.
23364+
The explicitly resolved syntax has the property that
23365+
each type has a unique syntactic form
23366+
(except for alpha equivalence, which is defined below).
23367+
We may then consider this unique syntactic form as a static semantic value,
23368+
rather than just a syntactic form which is dependent on
23369+
its location in the program.%
23370+
}
23371+
23372+
\LMHash{}%
23373+
The
23374+
\IndexCustom{explicitly resolved syntax}{type!explicitly resolved syntax of}
23375+
of the types in a given library $L_1$
23376+
and all libraries \List{L}{2}{n} reachable from $L_1$ via
23377+
one or more import links
23378+
is determined as follows.
23379+
First, choose a set of distinct, globally fresh identifiers
23380+
\List{\metavar{prefix}}{1}{n}.
23381+
Then transform each library $L_i$, $i \in 1 .. n$ as follows:
23382+
23383+
\begin{enumerate}
23384+
\item
23385+
For each type variable declared in $L_i$, consistently rename
23386+
it to a globally fresh name.
23387+
\item
23388+
If $D_T$ is a declaration of a class, mixin, or type alias in $L_i$
23389+
whose name $n$ is private,
23390+
and an occurrence of $n$ that resolves to $D$
23391+
exists in a type alias declaration $D_A$ whose name is non-private,
23392+
then perform a consistent renaming of
23393+
all occurrences of $n$ in $L_i$ that resolve to $D_T$
23394+
to a fresh, non-private identifier.
23395+
\commentary{%
23396+
We make $D_T$ public, because it is being leaked anyway.%
23397+
}
23398+
\item
23399+
Add a set of import directives to $L_i$ that imports
23400+
each of the libraries \List{L}{1}{n} with
23401+
the corresponding prefix $\metavar{prefix}_j$, $j \in 1 .. n$.
23402+
23403+
\commentary{%
23404+
This means that every library in the set
23405+
$\{\,\List{L}{1}{n}\,\}$
23406+
imports every other library in that set,
23407+
even itself and system libraries like \code{dart:core}.%
23408+
}
23409+
\item
23410+
Let \id{} be an occurrence of
23411+
a non-private type identifier derived from \synt{typeName}
23412+
that resolves to a library declaration in the library $L_j$
23413+
in the original program;
23414+
\id{} is then transformed to \code{$\metavar{prefix}_j$.\id}.
23415+
Let \code{$p$.\id} be derived from \synt{typeName} such that $p$ is
23416+
an import prefix in the original program
23417+
and \id{} is a non-private identifier,
23418+
and consider the case where \code{$p$.\id} resolves to
23419+
a library declaration in the library $L_j$ in the original program,
23420+
for some $j$;
23421+
\code{$p$.\id} is then transformed to \code{$\metavar{prefix}_j$.\id}.
23422+
\item
23423+
Replace every type in $L_i$ that denotes a type alias
23424+
along with its actual type arguments, if any,
23425+
by its transitive alias expansion
23426+
(\ref{typedef}).
23427+
\commentary{%
23428+
Note that the bodies of type alias declarations
23429+
already use the new prefixes,
23430+
so the results of the alias expansion will also use
23431+
the new prefixes consistently.%
23432+
}
23433+
\end{enumerate}
23434+
23435+
\commentary{%
23436+
In short, this transformation adds a unique prefix to every type name
23437+
which is resolved to a top-level declaration
23438+
(in the same library or in an imported library).
23439+
23440+
This transformation does not change any occurrence of \VOID,
23441+
and does not need to;
23442+
\VOID{} is a reserved word, not a type identifier.
23443+
Also, \code{$\metavar{prefix}_j$.\VOID} would be a syntax error.
23444+
23445+
Note that the transformation changes terms derived from \synt{type},
23446+
but it does not change expressions, or any other program element
23447+
(except that a \synt{type} can occur in an expression, e.g., \code{<int>[]}).
23448+
In particular, it does not change type literals
23449+
(that is, expressions denoting types).%
23450+
}
23451+
23452+
\LMHash{}%
23453+
Every \synt{type} in the resulting set of libraries
23454+
is now expressed in a globally unique syntactic form,
23455+
which is the form that we call the
23456+
\IndexCustom{explicitly resolved syntax of}{type!explicitly resolved syntax of}
23457+
said types.
23458+
23459+
\LMHash{}%
23460+
When we say that two types $T_1$ and $T_2$ have the
23461+
\IndexCustom{same explicitly resolved syntax}{type!same explicitly resolved syntax},
23462+
it refers to the situation where the current library
23463+
and all libraries which are reachable via one or more imports
23464+
have been transformed as described above,
23465+
and the resulting explicitly resolved syntaxes are textually identical.
23466+
23467+
\LMHash{}%
23468+
We need to introduce one more concept:
23469+
An \Index{alpha conversion} of a type is a consistent renaming
23470+
of the type variables declared in that type.
23471+
23472+
\commentary{%
23473+
In Dart, only function types can be subject to an alpha conversion:
23474+
A function type is the only kind of type that declares type variables.
23475+
For example,
23476+
\code{List<X>\,\,\FUNCTION<X>({X\,\,arg})}
23477+
can be turned into
23478+
\code{List<Y>\,\,\FUNCTION<Y>({Y\,\,arg})}
23479+
by alpha conversion.%
23480+
}
23481+
23482+
\LMHash{}%
23483+
Two function types are \Index{alpha equivalent} if{}f
23484+
there exists an alpha conversion that makes them textually identical.
23485+
23486+
\LMHash{}%
23487+
Finally, we define that two type denotations $T_1$ and $T_2$ are the
23488+
\IndexCustom{same static type}{type!same static}
23489+
if there exist alpha conversions
23490+
that can be applied to the function types
23491+
that occur as subterms of $T_1$ and $T_2$, if any,
23492+
such that the resulting terms $T'_1$ and $T'_2$ have
23493+
the same explicitly resolved syntax.
23494+
23495+
2330623496
\section{Reference}
2330723497
\LMLabel{reference}
2330823498

0 commit comments

Comments
 (0)