You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/DevelopmentTips.md
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -42,7 +42,7 @@ Given the size of artifacts generated, you might also want to bump the cache siz
42
42
43
43
You can run some compiles to see if it is actually doing something by running `sccache --show-stats`. Depending on the exact compilation task you're running, you might see very different cache hit rates. For example, `sccache` is particularly effective if you're rebuilding LLVM, which doesn't change so frequently from the Swift compiler's perspective. On the other hand, if you're changing the compiler's AST, the cache hit rate is likely to be much lower.
44
44
45
-
One known issue with `sccache` is that you might occassionally get an "error: Connection to server timed out", even though you didn't stop the server. Simply re-running the build command usually works.
45
+
One known issue with `sccache` is that you might occasionally get an "error: Connection to server timed out", even though you didn't stop the server. Simply re-running the build command usually works.
A particularly powerful kind of generic requirement---and perhaps the entire reason the requirement machine exists---is the same-type requirement.
220
220
221
-
Supppose you're working with $\genericparam{S}$, a generic parameter ranging over $\proto{Sequence}$. Writing $\genericparam{S}.\namesym{Iterator}.\namesym{Element}$ everywhere will get awkward fast. As I mentioned, the real version of $\proto{Sequence}$ in the standard library is slightly more complex. Indeed, it defines an $\namesym{Element}$ associated type in the protocol itself, so that the user can write $\genericparam{S}.\namesym{Element}$. Simply adding the associated type definition is not enough, because now $\genericparam{S}.\namesym{Element}$ and $\genericparam{S}.\namesym{Iterator}.\namesym{Element}$ are \emph{different} type parameters and cannot be used interchangeably.
221
+
Suppose you're working with $\genericparam{S}$, a generic parameter ranging over $\proto{Sequence}$. Writing $\genericparam{S}.\namesym{Iterator}.\namesym{Element}$ everywhere will get awkward fast. As I mentioned, the real version of $\proto{Sequence}$ in the standard library is slightly more complex. Indeed, it defines an $\namesym{Element}$ associated type in the protocol itself, so that the user can write $\genericparam{S}.\namesym{Element}$. Simply adding the associated type definition is not enough, because now $\genericparam{S}.\namesym{Element}$ and $\genericparam{S}.\namesym{Iterator}.\namesym{Element}$ are \emph{different} type parameters and cannot be used interchangeably.
222
222
223
223
\index{same-type requirement}
224
224
To express this restriction that concrete types conforming to $\proto{Sequence}$ must provide an iterator type compatible with the element type, a \texttt{where} clause in the protocol can state a same-type requirement:
One more small language feature is worth mentioning. You might want to define a function that constructs the the set of all subsets of a set, i.e., the power set. The $\namesym{Set}\langle\bullet\rangle$ type constructor requires that its argument conforms to $\proto{Hashable}$:
264
+
One more small language feature is worth mentioning. You might want to define a function that constructs the set of all subsets of a set, i.e., the power set. The $\namesym{Set}\langle\bullet\rangle$ type constructor requires that its argument conforms to $\proto{Hashable}$:
\begin{definition}[Reduction relation]\label{transinvdef} If $A^*$ is equipped with a reduction order $<$, then a relation $\rightarrow$ is a \emph{reduction relation} with respect to $<$ if $x\rightarrow y$ implies that $y<x$. Another equivalent definition is that a reduction relation $\rightarrow$ is a \emph{sub-relation} of $>$, the inverse relation of $<$.
1391
1391
\end{definition}
1392
1392
\index{rewrite system}
1393
-
As you saw in the previous example, a reduction relation for a finitely-presented monoid can be constructed by orienting the equations from the presentation with respect to some reduction order, a process which converts the equations into rewrite rules. Such a set of rewrite rules is called a \emph{rewrite system}. There is a simple algorithm for for reducing a term into an irreducible form:
1393
+
As you saw in the previous example, a reduction relation for a finitely-presented monoid can be constructed by orienting the equations from the presentation with respect to some reduction order, a process which converts the equations into rewrite rules. Such a set of rewrite rules is called a \emph{rewrite system}. There is a simple algorithm for reducing a term into an irreducible form:
1394
1394
\begin{algorithm}[Reducing a term]\label{reducingaterm} Let $t$ be a term in some rewrite system $R$.
This means that adding a new \emph{generator} to $M$ made the presentation convergent. What does this generator represent in the world of Swift? Well, $u\in M'$ is $a\in M$, which is $\protosym{View}$ in Swift; and $v\in M'$ is $b\in M$, which is $\namesym{Body}$. Therefore $t\in M'$ is $ab\in M$, which is $\protosym{View}.\namesym{Body}$. You may guess that $t$ could be a new kind of symbol, perhaps representing a ``bound'' associated type inside a specific protcol.
2211
+
This means that adding a new \emph{generator} to $M$ made the presentation convergent. What does this generator represent in the world of Swift? Well, $u\in M'$ is $a\in M$, which is $\protosym{View}$ in Swift; and $v\in M'$ is $b\in M$, which is $\namesym{Body}$. Therefore $t\in M'$ is $ab\in M$, which is $\protosym{View}.\namesym{Body}$. You may guess that $t$ could be a new kind of symbol, perhaps representing a ``bound'' associated type inside a specific protocol.
2212
2212
2213
2213
\index{associated type symbol}
2214
2214
The crux of the issue is that name symbols like $\namesym{Body}$ don't carry any information, and little can be said about them unless they're prefixed with some other term that is known to conform to a protocol. Thus, you cannot simply add a rewrite rule to say that $\namesym{Body}$ conforms to $\protosym{View}$:
This solves the quandry presented at the beginning of this chapter, where the earlier formulation of the rewrite system that lacked associated type symbols had no apparent way of implementing the \texttt{getCanonicalTypeInContext()} generic signature query.
2372
+
This solves the quandary presented at the beginning of this chapter, where the earlier formulation of the rewrite system that lacked associated type symbols had no apparent way of implementing the \texttt{getCanonicalTypeInContext()} generic signature query.
2373
2373
2374
2374
Now that a term containing name symbols reduces to a canonical term with associated type symbols, it appears that mapping terms back to fully resolved type parameters is now a possibility. Unfortunately, the reality is a little bit more complicated. The inherited associated type construction I will introduce in the next section once again breaks the correspondence between terms and canonical types; this will be repaired in Section \ref{implqueries}.
\item[\texttt{getRequiredProtocols()}] The list of protocol requirements satisfied by a type parameter $T$ is recorded in the form of protocol symbols in the property map. This list is transformed into a minimal canonical list of protocols using Definition~\ref{minimalproto}.
3675
3675
\index{layout constraints}
3676
3676
\index{join of layout constraints}
3677
-
\item[\texttt{getLayoutContraint()}] A type parameter $T$ might be subject to multiple layout constraints, in which case the property map entry will store a list of layout constraints $L_1,\ldots,L_n$. This query needs to compute their join, which is the largest layout constraint that simultaneously satisfies all of them:
3677
+
\item[\texttt{getLayoutConstraint()}] A type parameter $T$ might be subject to multiple layout constraints, in which case the property map entry will store a list of layout constraints $L_1,\ldots,L_n$. This query needs to compute their join, which is the largest layout constraint that simultaneously satisfies all of them:
3678
3678
\[L_1\wedge\cdots\wedge L_n.\]
3679
3679
Some layout constraints are disjoint on concrete types, meaning their join is the uninhabited ``bottom'' layout constraint, which precedes all other layout constraints in the partial order. In this case, the original generic signature is said to have conflicting requirements. While such a signature does not violate the requirement machine's invariants, it cannot be satisfied by any valid set of concrete substitutions. Detecting and diagnosing conflicting requirements is discussed later.
0 commit comments