Index: doc/generic_types/generic_types.tex
===================================================================
--- doc/generic_types/generic_types.tex	(revision 1e4f05e68a0cc389a37c3f17133c3feb44b2bc9b)
+++ doc/generic_types/generic_types.tex	(revision 89e1b16d05935066e64637eb65d157b36ee24ad0)
@@ -139,5 +139,5 @@
 \begin{lstlisting}
 forall(otype T)
-T identity(T x) {is_
+T identity(T x) {
     return x;
 }
@@ -294,5 +294,24 @@
 Since @pair(T*, T*)@ is a concrete type, there are no added implicit parameters to @lexcmp@, so the code generated by \CFA{} will be effectively identical to a version of this written in standard C using @void*@, yet the \CFA{} version will be type-checked to ensure that the fields of both pairs and the arguments to the comparison function match in type.
 
-\TODO{} The second is zero-cost ``tag'' structs.
+Another useful pattern enabled by re-used dtype-static type instantiations is zero-cost ``tag'' structs. Sometimes a particular bit of information is only useful for type-checking, and can be omitted at runtime. Tag structs can be used to provide this information to the compiler without further runtime overhead, as in the following example:
+\begin{lstlisting}
+forall(dtype Unit) struct scalar { unsigned long value; };
+
+struct metres {};
+struct litres {};
+
+forall(dtype U)
+scalar(U) ?+?(scalar(U) a, scalar(U) b) {
+	return (scalar(U)){ a.value + b.value };
+}
+
+scalar(metres) half_marathon = { 21093 };
+scalar(litres) swimming_pool = { 2500000 };
+
+scalar(metres) marathon = half_marathon + half_marathon;
+scalar(litres) two_pools = swimming_pool + swimming_pool;
+marathon + swimming_pool; // ERRORv -- caught by compiler
+\end{lstlisting}
+@scalar@ is a dtype-static type, so all uses of it will use a single struct definition, containing only a single @unsigned long@, and can share the same implementations of common routines like @?+?@ -- these implementations may even be separately compiled, unlike \CC{} template functions. However, the \CFA{} type-checker will ensure that matching types are used by all calls to @?+?@, preventing nonsensical computations like adding the length of a marathon to the volume of an olympic pool.
 
 \section{Tuples}
