Skip to content

Commit fc795b4

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

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
@@ -2677,7 +2677,7 @@ \subsection{Type of a Function}
26772677
different type parameters, F-bounds, and the types of formal parameters.
26782678
However, we do not wish to distinguish between two function types
26792679
if they have the same structure and only differ in the choice of names.
2680-
This treatment of names is also known as alpha-equivalence.%
2680+
This treatment of names is also known as alpha equivalence.%
26812681
}
26822682

26832683
\LMHash{}%
@@ -22029,24 +22029,18 @@ \subsubsection{Subtype Rules}
2202922029
However, we must eliminate the difficulties associated with
2203022030
different syntax denoting the same type,
2203122031
and different types denoted by the same syntax.
22032-
We do this by assuming that every type in the program has been expressed
22033-
in a manner where those situations never occur,
22034-
because each type is denoted by the same globally unique syntax everywhere.%
22032+
We do this by defining in detail what it means to be the same type
22033+
(\ref{sameStaticType}).%
2203522034
}
2203622035

2203722036
\LMHash{}%
2203822037
In section~\ref{subtypes} and its subsections,
2203922038
all designations of types are considered to be the same
22040-
if{}f they have the same canonical syntax
22041-
(\ref{theCanonicalSyntaxOfTypes}).
22039+
type if{}f they satisfy the criteria in
22040+
Section~\ref{sameStaticType}.
2204222041

22043-
\commentary{%
22044-
Note that the canonical syntax also implies
22045-
transitive expansion of all type aliases
22046-
(\ref{typedef}).
22047-
In other words, subtyping rules do not need to consider type aliases,
22048-
because all type aliases have been expanded.%
22049-
}
22042+
\LMHash{}%
22043+
The subtype rules assume that all type aliases have been transitively expanded.
2205022044

2205122045
\LMHash{}%
2205222046
Every \synt{typeName} used in a type mentioned
@@ -22432,19 +22426,13 @@ \subsection{Function Types}
2243222426
coincide in this case.%
2243322427
}
2243422428

22435-
\LMHash{}%
22436-
Two function types are considered equal if consistent renaming of type
22437-
parameters can make them identical.
22438-
2243922429
\commentary{%
22440-
A common way to say this is that we do not distinguish
22441-
function types which are alpha-equivalent.
22442-
For the subtyping rule below this means we can assume that
22443-
a suitable renaming has already taken place.
22444-
In cases where this is not possible
22445-
because the number of type parameters in the two types differ
22446-
or the bounds are different,
22447-
no subtype relationship exists.%
22430+
Two function types are the same type
22431+
if, roughly, consistent renaming of type
22432+
parameters can make them identical.
22433+
This is also known as alpha equivalence.
22434+
The detailed rules are described in
22435+
Section~\ref{sameStaticType}.%
2244822436
}
2244922437

2245022438
\LMHash{}%
@@ -23331,6 +23319,208 @@ \subsubsection{Least Upper Bounds}
2333123319
}
2333223320

2333323321

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

0 commit comments

Comments
 (0)