Index: doc/user/user.tex
===================================================================
--- doc/user/user.tex	(revision c185ca93fa534f3ae92d87dbb7a0b035f0459df8)
+++ doc/user/user.tex	(revision cdd25ef9f6abfd796a8899f9682eff0e020a1453)
@@ -11,6 +11,6 @@
 %% Created On       : Wed Apr  6 14:53:29 2016
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Mon Feb 12 11:50:26 2024
-%% Update Count     : 6199
+%% Last Modified On : Thu Apr 18 21:53:45 2024
+%% Update Count     : 6502
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -130,5 +130,5 @@
 \vspace*{\fill}
 \noindent
-\copyright\,2016, 2018, 2021 \CFA Project \\ \\
+\copyright\,2016, 2018, 2021, 2024 \CFA Project \\ \\
 \noindent
 This work is licensed under the Creative Commons Attribution 4.0 International License.
@@ -312,5 +312,5 @@
 For example, it is possible to write a type-safe \CFA wrapper ©malloc© based on the C ©malloc©:
 \begin{cfa}
-forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }
+forall( T & | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }
 int * ip = malloc(); §\C{// select type and size from left-hand side}§
 double * dp = malloc();
@@ -1023,47 +1023,47 @@
 while () { sout | "empty"; break; }
 do { sout | "empty"; break; } while ();
-for () { sout | "empty"; break; }							§\C{sout | nl | nlOff;}§
-
-for ( 0 ) { sout | "A"; } sout | "zero";					§\C{sout | nl;}§
-for ( 1 ) { sout | "A"; }									§\C{sout | nl;}§
-for ( 10 ) { sout | "A"; }									§\C{sout | nl;}§
-for ( ~= 10 ) { sout | "A"; }								§\C{sout | nl;}§
-for ( 1 ~= 10 ~ 2 ) { sout | "B"; }							§\C{sout | nl;}§
-for ( 1 -~= 10 ~ 2 ) { sout | "C"; }						§\C{sout | nl;}§
-for ( 0.5 ~ 5.5 ) { sout | "D"; }							§\C{sout | nl;}§
-for ( 0.5 -~ 5.5 ) { sout | "E"; }							§\C{sout | nl;}§
-for ( i; 10 ) { sout | i; }									§\C{sout | nl;}§
-for ( i; ~= 10 ) { sout | i; }								§\C{sout | nl;}§
-for ( i; 1 ~= 10 ~ 2 ) { sout | i; }						§\C{sout | nl;}§
-for ( i; 1 -~= 10 ~ 2 ) { sout | i; }						§\C{sout | nl;}§
-for ( i; 0.5 ~ 5.5 ) { sout | i; }							§\C{sout | nl;}§
-for ( i; 0.5 -~ 5.5 ) { sout | i; }							§\C{sout | nl;}§
-for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; }					§\C{sout | nl;}§
-for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; }					§\C{sout | nl | nl | nl;}§
+for () { sout | "empty"; break; }				§\C[3in]{sout | nl | nlOff;}§
+
+for ( 0 ) { sout | "A"; } sout | "zero";		§\C{sout | nl;}§
+for ( 1 ) { sout | "A"; }						§\C{sout | nl;}§
+for ( 10 ) { sout | "A"; }						§\C{sout | nl;}§
+for ( ~= 10 ) { sout | "A"; }					§\C{sout | nl;}§
+for ( 1 ~= 10 ~ 2 ) { sout | "B"; }				§\C{sout | nl;}§
+for ( 1 -~= 10 ~ 2 ) { sout | "C"; }			§\C{sout | nl;}§
+for ( 0.5 ~ 5.5 ) { sout | "D"; }				§\C{sout | nl;}§
+for ( 0.5 -~ 5.5 ) { sout | "E"; }				§\C{sout | nl;}§
+for ( i; 10 ) { sout | i; }						§\C{sout | nl;}§
+for ( i; ~= 10 ) { sout | i; }					§\C{sout | nl;}§
+for ( i; 1 ~= 10 ~ 2 ) { sout | i; }			§\C{sout | nl;}§
+for ( i; 1 -~= 10 ~ 2 ) { sout | i; }			§\C{sout | nl;}§
+for ( i; 0.5 ~ 5.5 ) { sout | i; }				§\C{sout | nl;}§
+for ( i; 0.5 -~ 5.5 ) { sout | i; }				§\C{sout | nl;}§
+for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; }		§\C{sout | nl;}§
+for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; }		§\C{sout | nl | nl | nl;}§
 
 enum { N = 10 };
-for ( N ) { sout | "N"; }									§\C{sout | nl;}§
-for ( i; N ) { sout | i; }									§\C{sout | nl;}§
-for ( i; -~ N ) { sout | i; }								§\C{sout | nl | nl | nl;}§
+for ( N ) { sout | "N"; }						§\C{sout | nl;}§
+for ( i; N ) { sout | i; }						§\C{sout | nl;}§
+for ( i; -~ N ) { sout | i; }					§\C{sout | nl | nl | nl;}§
 
 const int low = 3, high = 10, inc = 2;
-for ( i; low ~ high ~ inc + 1 ) { sout | i; }				§\C{sout | nl;}§
-for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; }			§\C{sout | nl;}§
-for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; }		§\C{sout | nl;}§
-for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; }		§\C{sout | nl;}§
+for ( i; low ~ high ~ inc + 1 ) { sout | i; }	§\C{sout | nl;}§
+for ( i; 1 ~ @ ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§
+for ( i; @ -~ 10 ) { if ( i < 0 ) break; sout | i; } §\C{sout | nl;}§
+for ( i; 2 ~ @ ~ 2 ) { if ( i > 10 ) break; sout | i; } §\C{sout | nl;}§
 for ( i; 2.1 ~ @ ~ @ ) { if ( i > 10.5 ) break; sout | i; i += 1.7; } §\C{sout | nl;}§
 for ( i; @ -~ 10 ~ 2 ) { if ( i < 0 ) break; sout | i; }	§\C{sout | nl;}§
 for ( i; 12.1 ~ @ ~ @ ) { if ( i < 2.5 ) break; sout | i; i -= 1.7; } §\C{sout | nl;}§
-for ( i; 5 : j; -5 ~ @ ) { sout | i | j; }					§\C{sout | nl;}§
-for ( i; 5 : j; @ -~ -5 ) { sout | i | j; }					§\C{sout | nl;}§
-for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; }				§\C{sout | nl;}§
-for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; }				§\C{sout | nl;}§
-for ( i; 5 : j; -5 ~ @ ) { sout | i | j; }					§\C{sout | nl;}§
-for ( i; 5 : j; @ -~ -5 ) { sout | i | j; }					§\C{sout | nl;}§
-for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; }				§\C{sout | nl;}§
-for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; }				§\C{sout | nl;}§
+for ( i; 5 : j; -5 ~ @ ) { sout | i | j; }		§\C{sout | nl;}§
+for ( i; 5 : j; @ -~ -5 ) { sout | i | j; }		§\C{sout | nl;}§
+for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; }	§\C{sout | nl;}§
+for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; }	§\C{sout | nl;}§
+for ( i; 5 : j; -5 ~ @ ) { sout | i | j; }		§\C{sout | nl;}§
+for ( i; 5 : j; @ -~ -5 ) { sout | i | j; }		§\C{sout | nl;}§
+for ( i; 5 : j; -5 ~ @ ~ 2 ) { sout | i | j; }	§\C{sout | nl;}§
+for ( i; 5 : j; @ -~ -5 ~ 2 ) { sout | i | j; }	§\C{sout | nl;}§
 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§
 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§
-for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;}§
+for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;}\CRT§
 \end{cfa}
 &
@@ -2960,4 +2960,6 @@
 The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter ©x© of type array of 5 integers.
 Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string.
+
+{\color{red}
 As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity:
 \begin{cfa}
@@ -2967,5 +2969,5 @@
 The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
 The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type qualifier characters appearing to the right of the type name.
-The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.
+The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.}
 
 C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
@@ -3055,4 +3057,157 @@
 static [ int ] g ( int );
 \end{cfa}
+
+
+\subsection{Postfix Function}
+\label{s:PostfixFunction}
+
+\CFA provides an alternative call syntax where the argument appears before the function name.
+The syntax uses the backquote ©`© to separate the parameters/arguments and function name: ©?`© denotes a postfix-function name, \eg ©int ?`h( int s )© and ©`© denotes a postfix-function call, \eg ©0`h© meaning ©h( 0 )©.
+\begin{cquote}
+\begin{tabular}{@{}l|l|l|l@{}}
+postfix function & constant argument call & variable argument call & postfix function pointer \\
+\hline
+\begin{cfa}
+int ?`h( int s );
+int ?`h( double s );
+int ?`m( char c );
+int ?`m( const char * s );
+int ?`t( int a, int b, int c );
+\end{cfa}
+&	
+\begin{cfa}
+0`h;
+3.5`h;
+'1'`m;
+"123" "456"`m;
+[1,2,3]`t;
+\end{cfa}
+&	
+\begin{cfa}
+int i = 7;
+i`h;
+(i + 3)`h;
+(i + 3.5)`h;
+\end{cfa}
+&	
+\begin{cfa}
+int (* ?`p)( int i );
+?`p = ?`h;
+3`p;
+i`p;
+(i + 3)`p;
+\end{cfa}
+\end{tabular}
+\end{cquote}
+
+\VRef[Figure]{f:UnitsComparison} shows a common usage for postfix functions: converting basic literals into user literals.
+\see*{\VRef{s:DynamicStorageManagement} for other uses for postfix functions.}
+The \CFA example (left) stores a mass in units of stones (1 stone = 14 lb or 6.35 kg) and provides an addition operator (imagine a full set of arithmetic operators).
+The three postfixing function names ©st©, ©lb©, and ©kg©, represent units stones, pounds, and kilograms, respectively.
+Each name has two forms that bidirectional convert: a value of a specified unit to stones, \eg ©w = 14`lb© $\Rightarrow$ ©w == 1© stone or a ©Weight© from stones back to specific units, \eg ©w`lb© (1 stone) to ©14©.
+All arithmetic operations manipulate stones and the postfix operations convert to the different units.
+A similar group of postfix functions provide user constants for converting time units into nanoseconds, which is the basic time unit, \eg ©ns©, ©us©, ©ms©, ©s©, ©m©, ©h©, ©d©, and ©w©, for nanosecond, microsecond, millisecond, second, minute, hour, day, and week, respectively.
+(Note, month is not a fixed period of time nor is year because of leap years.)
+
+\begin{figure}
+\centering
+\begin{tabular}{@{}l|l@{}}
+\multicolumn{1}{@{}c|}{\textbf{\CFA Postfix Routine}} & \multicolumn{1}{c@{}}{\textbf{\CC User Literals}} \\
+\hline
+\begin{cfa}
+struct Weight {
+	double stones;
+};
+
+
+Weight ?+?( Weight l, Weight r ) {
+	return l.stones + r.stones;
+}
+Weight ?`st( double w ) { return w; }
+double ?`st( Weight w ) { return w.stones; }
+Weight ?`lb( double w ) { return w / 14.0; }
+double ?`lb( Weight w ) { return w.stones * 14.0; }
+Weight ?`kg( double w ) { return w / 6.35; }
+double ?`kg( Weight w ) { return w.stones * 6.35; }
+int main() {
+	Weight w, heavy = { 20 }; // stones
+	w = 155`lb;
+	w = 0b_1111`st;
+	w = 0_233`lb;
+	w = 0x_9b`kg;
+	w = 5.5`st + 8`kg + 25.01`lb + heavy;
+}
+\end{cfa}
+&
+\begin{C++}
+struct Weight {
+	double stones;
+	Weight() {}
+	Weight( double w ) { stones = w; }
+};
+Weight operator+( Weight l, Weight r ) {
+	return l.stones + r.stones;
+}
+Weight operator""_st( long double w ) { return w; }
+Weight operator""_lb( long double w ) { return w / 14.0; }
+Weight operator""_kg( long double w ) { return w / 6.35; }
+Weight operator""_st( unsigned long long int w ) { return w; }
+Weight operator""_lb( unsigned long long int w ) { return w / 14.0; }
+Weight operator""_kg( unsigned long long int w ) { return w / 6.35; }
+int main() {
+	Weight w, heavy = { 20 }; // stones
+	w = 155_lb;
+	w = 0b1111_st;
+	w = 0'233_lb;		// quote separator
+	w = 0x9b_kg;
+	w = 5.5_st + 8_kg + 25.01_lb + heavy;
+}
+\end{C++}
+\end{tabular}
+
+\begin{comment}
+Time : comparison of time units. \\
+\begin{tabular}{@{}ll@{}}
+\CFA & \CC \\
+\begin{cfa}
+#include <fstream.hfa>
+#include <time.hfa>
+
+
+Duration s = 1`h + 2 * 10`m + 70`s / 10;
+sout | "1 hour + 2*10 min + 70/10 sec = " | s | "seconds";
+sout | "Dividing that by 2 minutes gives" | s / 2`m;
+sout | "Dividing that by 2 gives" | s / 2 | "seconds\n";
+sout | s | "seconds is"
+	  | s`h | "hours,"
+	  | (s % 1`h)`m | "minutes,"
+	  | (s % 1`m)`s | "seconds";
+\end{cfa}
+&	
+\begin{C++}
+#include <iostream>
+#include <chrono>
+using namespace std;
+using namespace std::chrono;
+seconds s = hours(1) + 2 * minutes(10) + seconds(70) / 10;
+cout << "1 hour + 2*10 min + 70/10 sec = " << s.count() << " seconds\n";
+cout << "Dividing that by 2 minutes gives " << s / minutes(2) << '\n';
+cout << "Dividing that by 2 gives " << (s / 2).count() << " seconds\n";
+cout << s.count() << " seconds is "
+	  << duration_cast<hours>( s ).count() << " hours, "
+	  << duration_cast<minutes>( s % hours(1) ).count() << " minutes, "
+	  << duration_cast<seconds>( s % minutes(1) ).count() << " seconds\n";
+\end{C++}
+\end{tabular}
+\end{comment}
+
+\caption{Units: Stone, Pound, Kilogram Comparison}
+\label{f:UnitsComparison}
+\end{figure}
+
+The \CC example (right) provides a \emph{restricted} capability via user literals.
+The \lstinline[language=C++]{operator ""} only takes a constant argument (\ie no variable argument), and the constant type must be the highest-level constant-type, \eg ©long double© for all floating-point constants.
+As well, there is no constant conversion, \ie ©int© to ©double© constants, so integral constants are handled by a separate set of routines, with maximal integral type ©unsigned long long int©.
+Finally, there is no mechanism to use this syntax for a bidirectional conversion because \lstinline[language=C++]{operator ""} does not accept variable arguments.
 
 
@@ -3809,8 +3964,8 @@
 \subsection{Polymorphism}
 
-Due to the implicit flattening and structuring conversions involved in argument passing, ©otype© and ©dtype© parameters are restricted to matching only with non-tuple types.
+Due to the implicit flattening and structuring conversions involved in argument passing, object and opaque parameters are restricted to matching only with non-tuple types.
 The integration of polymorphism, type assertions, and monomorphic specialization of tuple-assertions are a primary contribution of this thesis to the design of tuples.
 \begin{cfa}
-forall(T, dtype U)
+forall(T, U &)
 void f(T x, U * y);
 
@@ -4925,8 +5080,8 @@
 	sout | '1' | '2' | '3';
 	sout | 1 | "" | 2 | "" | 3;
-	sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x Â£" | 6 | "x Â¥"
-		| 7 | "x Â¡" | 8 | "x Â¿" | 9 | "x Â«" | 10;
+	sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥"
+		| 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;
 	sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
-		| 7 | "Â¢ x" | 8 | "Â» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";
+		| 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";
 	sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx";
 	sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4;
@@ -7775,5 +7930,5 @@
 \item[Rationale:] increase type safety
 \item[Effect on original feature:] deletion of semantically well-defined feature.
-\item[Difficulty of converting:] requires adding a cast \see{\VRef{s:StorageManagement} for better alternatives}:
+\item[Difficulty of converting:] requires adding a cast \see{\VRef{s:DynamicStorageManagement} for better alternatives}:
 \begin{cfa}
 	int * b = (int *)malloc( sizeof(int) );
@@ -7988,151 +8143,301 @@
 \label{s:StandardLibrary}
 
-The \CFA standard-library wraps explicitly-polymorphic C routines into implicitly-polymorphic versions.
-
-
-\subsection{Storage Management}
-\label{s:StorageManagement}
-
-The storage-management routines extend their C equivalents by overloading, alternate names, providing shallow type-safety, and removing the need to specify the allocation size for non-array types.
-
-C storage management provides the following capabilities:
-\begin{description}
-\item[filled]
-after allocation with a specified character or value.
+The \CFA standard-library extends existing C library routines by adding new function, wrapping existing explicitly-polymorphic C routines into implicitly-polymorphic versions, and adding new \CFA extensions.
+
+
+\subsection{Dynamic Storage-Management}
+\label{s:DynamicStorageManagement}
+
+Dynamic storage-management in C is based on explicit allocation and deallocation (©malloc©/©free©).
+Programmer's must manage all allocated storage via its address (pointer) and subsequently deallocate the storage via this address.
+Storage that is not deallocated becomes inaccessible, called a \newterm{memory leak}, which can only be detected at program termination.
+Storage freed twice is an error, called a \newterm{duplicate free}, which can sometimes be detected.
+Storage used after it is deallocated is an error, called using a \newterm{dangling pointer}, which can sometimes be detected.
+
+
+\subsubsection{C Interface}
+
+C dynamic storage-management provides the following properties.
+\begin{description}[leftmargin=*]
+\item[fill]
+storage after an allocation with a specified character or value.
+\item[align]
+an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes.
+\item[scale]
+an allocation size to the specified number of array elements.
+An array may be filled, resized, or aligned.
 \item[resize]
 an existing allocation to decreased or increased its size.
-In either case, new storage may or may not be allocated and, if there is a new allocation, as much data from the existing allocation is copied into the new allocation.
-For an increase in storage size, new storage after the copied data may be filled.
-\item[align]
-an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes.
-\item[array]
-the allocation size is scaled to the specified number of array elements.
-An array may be filled, resized, or aligned.
+In either direction, new storage may or may not be allocated, but if there is a new allocation, as much data from the existing allocation is copied into the new allocation.
+When new storage is allocated, it may be aligned and storage after copied data may be filled.
 \end{description}
-\VRef[Table]{t:AllocationVersusCapabilities} shows allocation routines supporting different combinations of storage-management capabilities.
+\VRef[Table]{t:AllocationVersusProperties} shows different combinations of storage-management properties provided by the C and \CFA allocation routines.
+
 \begin{table}
+\caption{Allocation Routines versus Storage-Management Properties}
+\label{t:AllocationVersusProperties}
 \centering
 \begin{minipage}{0.75\textwidth}
 \begin{tabular}{@{}r|l|l|l|l|l@{}}
-\multicolumn{1}{c}{}&		& \multicolumn{1}{c|}{fill}	& resize	& alignment	& array	\\
+		& \multicolumn{1}{c|}{routine} & \multicolumn{1}{c|}{\textbf{fill}} & \textbf{alignment}	& \textbf{scale}	& \textbf{resize} \\
 \hline
 C		& ©malloc©			& no			& no		& no		& no	\\
-		& ©calloc©			& yes (0 only)	& no		& no		& yes	\\
-		& ©realloc©			& copy			& yes		& no		& no	\\
-		& ©memalign©		& no			& no		& yes		& no	\\
-		& ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment, which is universally ignored.}
-							& no			& no		& yes		& no	\\
-		& ©posix_memalign©	& no			& no		& yes		& no	\\
-		& ©valloc©			& no			& no		& yes (page size)& no	\\
+		& ©calloc©			& yes (0 only)	& no		& yes		& no	\\
+		& ©realloc©			& copy			& no		& no		& yes	\\
+		& ©reallocarray©	& copy			& no		& yes		& yes	\\
+		& ©memalign©		& no			& yes		& no		& no	\\
+		& ©aligned_alloc©\footnote{Same as ©memalign© but size is an integral multiple of alignment.}
+							& no			& yes		& no		& no	\\
+		& ©posix_memalign©	& no			& yes		& no		& no	\\
+		& ©valloc©			& no			& yes (page size)& no	& no	\\
 		& ©pvalloc©\footnote{Same as ©valloc© but rounds size to multiple of page size.}
-							& no			& no		& yes (page size)& no	\\
-\hline
-\CFA	& ©cmemalign©		& yes (0 only)	& no		& yes		& yes	\\
-		& ©realloc©			& copy			& yes		& yes		& no	\\
-		& ©alloc©			& no			& yes		& no		& yes	\\
-		& ©alloc_set©		& yes			& yes		& no		& yes	\\
-		& ©alloc_align©		& no			& yes		& yes		& yes	\\
-		& ©alloc_align_set©	& yes			& yes		& yes		& yes	\\
+							& no			& yes (page size)& no	& no	\\
+\hline																        
+\CFA	& ©cmemalign©		& yes (0 only)	& yes		& yes		& no	\\
+		& ©resize©			& no copy		& yes		& no		& yes	\\
+		& ©realloc©			& copy			& yes		& no		& yes	\\
+		& ©alloc©\footnote{Multiple overloads with different parameters.}
+							& yes			& yes		& yes		& yes
 \end{tabular}
 \end{minipage}
-\caption{Allocation Routines versus Storage-Management Capabilities}
-\label{t:AllocationVersusCapabilities}
+\vspace*{-10pt}
 \end{table}
 
-\CFA memory management extends the type safety of all allocations by using the type of the left-hand-side type to determine the allocation size and return a matching type for the new storage.
-Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in
-\begin{cfa}
-int * ip = (int *)malloc( sizeof(int) ); §\C{// C}§
-int * ip = malloc();					§\C{// \CFA type-safe version of C malloc}§
-int * ip = alloc();						§\C{// \CFA type-safe uniform alloc}§
-\end{cfa}
-the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©.
-
-\CFA memory management extends allocation safety by implicitly honouring all alignment requirements, \eg in
-\begin{cfa}
-struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment
-S * sp = malloc();						§\C{// honour type alignment}§
-\end{cfa}
-the storage allocation is implicitly aligned to 128 rather than the default 16.
-The alignment check is performed at compile time so there is no runtime cost.
-
-\CFA memory management extends the resize capability with the notion of \newterm{sticky properties}.
-Hence, initial allocation capabilities are remembered and maintained when resize requires copying.
-For example, an initial alignment and fill capability are preserved during a resize copy so the copy has the same alignment and extended storage is filled.
-Without sticky properties it is dangerous to use ©realloc©, resulting in an idiom of manually performing the reallocation to maintain correctness.
-\begin{cfa}
-
-\end{cfa}
-
-\CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in
-\begin{cfa}
-struct S { int i; };					§\C{// cache-line alignment}§
-void ?{}( S & s, int i ) { s.i = i; }
-// assume ?|? operator for printing an S
-
-S & sp = *®new®( 3 );					§\C{// call constructor after allocation}§
-sout | sp.i;
-®delete®( &sp );
-
-S * spa = ®anew®( 10, 5 );				§\C{// allocate array and initialize each array element}§
-for ( i; 10 ) sout | spa[i] | nonl;
-sout | nl;
-®adelete®( 10, spa );
+
+\subsubsection{\CFA Interface}
+
+\CFA dynamic memory management:
+\begin{enumerate}[leftmargin=\parindent]
+\item
+Extend type safety of all allocation routines by using the left-hand assignment type to determine the allocation size and alignment, and return a matching type for the new storage, which removes many common allocation errors.
+\begin{cfa}
+int * ip = (int *)malloc( sizeof(int) ); §\C[2.3in]{// C}§
+int * ip = malloc();					§\C{// \CFA type-safe call of C malloc}§
+int * ip = alloc();						§\C{// \CFA type-safe call of \CFA alloc}§
+struct __attribute__(( aligned(128) )) spinlock { ... };
+spinlock * slp = malloc();				§\C{// correct size, alignment, and return type}\CRT§
+\end{cfa}
+Here, the alignment of the ©ip© storage is 16 (default) and 128 for ©slp©.
+
+\item
+Introduce the notion of \newterm{sticky properties} used in resizing.
+All initial allocation properties are remembered and maintained for use should resize require new storage.
+For example, the initial alignment and fill properties in the initial allocation
+\begin{cfa}
+struct __attribute__(( aligned(4096) )) S { ... };
+S * sp = calloc( 10 );					§\C{// align 4K and zero fill}§
+sp = reallocarray( sp, 100 );			§\C{// preserve 4K alignment and zero fill new storage}§
+\end{cfa}
+are preserved in the resize so the new storage has the same alignment and extra storage after the data copy is zero filled.
+Without sticky properties it is dangerous to resize, resulting in the C idiom of manually performing the reallocation to maintain correctness, which is error prone.
+
+\item
+Provide resizing without data copying, which is useful to repurpose an existing block of storage for another purpose, rather than freeing the old storage and performing a new allocation.
+The resize might be able to take advantage of unused storage after the data to preventing the free/reallocation step altogether.
+
+\item
+Provide ©free©/©delete© functions that delete a variable number of pointers.
+\begin{cfa}
+int * ip = malloc(), * jp = malloc(), * kp = malloc(); 
+double * xp = malloc(), * yp = malloc(), * zp = malloc(); 
+free( ®ip, jp, kp, xp, yp, zp® );
+\end{cfa}
+
+\item
+Support constructors for initialization of allocated storage (like \CC) and destructors for deallocation.
+\begin{cfa}
+struct S { int v; };					§\C{// default constructors}§
+void ^?{}( S & ) { ... }				§\C{// destructor}§
+S & sp = *®new®( 3 );					§\C{// allocate and call constructor}§
+sout | sp.v;
+®delete®( &sp );						§\C{// call destructor}§
+S * spa1 = ®anew®( 10, 5 ), * spa2 = ®anew®( 10, 8 ); §\C{// allocate array and call constructor for each array element}§
+for ( i; 10 ) sout | spa1[i].v | spa2[i].v | nonl; sout | nl;
+®adelete®( spa1, spa2 );				§\C{// call destructors on all array objects}§
+
+3
+5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8 5 8
 \end{cfa}
 Allocation routines ©new©/©anew© allocate a variable/array and initialize storage using the allocated type's constructor.
 Note, the matching deallocation routines ©delete©/©adelete©.
-
-\leavevmode
+\end{enumerate}
+
+In addition, \CFA provides a new allocator interface to further increase orthogonality and usability of dynamic-memory allocation.
+This interface helps programmers in three ways.
+\begin{enumerate}
+\item
+naming: \CFA regular and ©ttype© polymorphism (similar to \CC variadic templates) is used to encapsulate a wide range of allocation functionality into a single routine name, so programmers do not have to remember multiple routine names for different kinds of dynamic allocations.
+\item
+named arguments: individual allocation properties are specified using postfix function call \see{\VRef{s:PostfixFunction}}, so programmers do not have to remember parameter positions in allocation calls.
+\item
+safe usage: like the \CFA's C-interface, programmers do not have to specify object size or cast allocation results.
+\end{enumerate}
+
+The polymorphic functions ©T * alloc( ... )© and ©T * alloc( size_t dim, ... )© are overloaded with a variable number of specific allocation properties, or an integer dimension parameter followed by a variable number of specific allocation properties.
+These allocation properties can be passed as named arguments when calling the \lstinline{alloc} routine.
+A call without parameters returns an uninitialized dynamically allocated object of type ©T© (©malloc©).
+A call with only the dimension (dim) parameter returns an uninitialized dynamically allocated array of objects with type ©T© (©aalloc©).
+The variable number of arguments consist of allocation properties, which can be combined to produce different kinds of allocations.
+The properties ©resize© and ©realloc© are associated with the allocation variable indicating how the existing allocation is modified, without or with data copying.
+Function ©alloc© is used extensively in the \CFA runtime.
+
+The following allocation property functions may be combined and appear in any order as arguments to ©alloc©,
+\begin{itemize}
+\item
+©T_align ?`align( size_t alignment )© to align an allocation.
+The alignment parameter must be $\ge$ the default alignment (©libAlign()© in \CFA) and a power of two, \eg:
+\begin{cfa}
+int * i0 = alloc( ®4096`align® );  sout | i0 | nl;
+int * i1 = alloc( 3, ®4096`align® );  sout | i1; for (i; 3 ) sout | &i1[i] | nonl; sout | nl;
+
+0x555555572000
+0x555555574000 0x555555574000 0x555555574004 0x555555574008
+\end{cfa}
+returns a dynamic object and object array aligned on a 4096-byte boundary.
+
+\item
+©S_fill(T) ?`fill ( /* various types */ )© to initialize storage.
+There are three ways to fill storage:
+\begin{enumerate}
+\item
+A ©char© fills every byte of each object.
+\item
+An object of the returned type fills each object.
+\item
+An object array pointer fills some or all of the corresponding object array.
+\end{enumerate}
+For example:
+\begin{cfa}[numbers=left]
+int * i0 = alloc( ®0n`fill® );  sout | *i0 | nl;  // 0n disambiguates 0
+int * i1 = alloc( ®5`fill® );  sout | *i1 | nl;
+int * i2 = alloc( ®'\xfe'`fill® ); sout | hex( *i2 ) | nl;
+int * i3 = alloc( 5, ®5`fill® );  for ( i; 5 ) sout | i3[i] | nonl; sout | nl;
+int * i4 = alloc( 5, ®0xdeadbeefN`fill® );  for ( i; 5 ) sout | hex( i4[i] ) | nonl; sout | nl;
+int * i5 = alloc( 5, ®i3`fill® );  for ( i; 5 ) sout | i5[i] | nonl; sout | nl; // completely fill from i3
+int * i6 = alloc( 5, ®[i3, 3]`fill® );  for ( i; 5 ) sout | i6[i] | nonl; sout | nl; // partial fill from i3
+\end{cfa}
+\begin{lstlisting}[numbers=left]
+0
+5
+0xfefefefe
+5 5 5 5 5
+0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
+5 5 5 5 5
+5 5 5 -555819298 -555819298  // two undefined values
+\end{lstlisting}
+Examples 1 to 3 fill an object with a value or characters.
+Examples 4 to 7 fill an array of objects with values, another array, or part of an array.
+
+\item
+©S_resize(T) ?`resize( void * oaddr )© used to resize, realign, and fill, where the old object data is not copied to the new object.
+The old object type may be different from the new object type, since the values are not used.
+For example:
+\begin{cfa}[numbers=left]
+int * i = alloc( ®5`fill® );  sout | i | *i;
+i = alloc( ®i`resize®, ®256`align®, ®7`fill® );  sout | i | *i;
+double * d = alloc( ®i`resize®, ®4096`align®, ®13.5`fill® );  sout | d | *d;
+\end{cfa}
+\begin{lstlisting}[numbers=left]
+0x55555556d5c0 5
+0x555555570000 7
+0x555555571000 13.5
+\end{lstlisting}
+Examples 2 to 3 change the alignment, fill, and size for the initial storage of ©i©.
+
+\begin{cfa}[numbers=left]
+int * ia = alloc( 5, ®5`fill® );  for ( i; 5 ) sout | ia[i] | nonl; sout | nl;
+ia = alloc( 10, ®ia`resize®, ®7`fill® ); for ( i; 10 ) sout | ia[i] | nonl; sout | nl;
+sout | ia; ia = alloc( 5, ®ia`resize®, ®512`align®, ®13`fill® ); sout | ia; for ( i; 5 ) sout | ia[i] | nonl; sout | nl;;
+ia = alloc( 3, ®ia`resize®, ®4096`align®, ®2`fill® );  sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i] | nonl; sout | nl;
+\end{cfa}
+\begin{lstlisting}[numbers=left]
+5 5 5 5 5
+7 7 7 7 7 7 7 7 7 7
+0x55555556d560 0x555555571a00 13 13 13 13 13
+0x555555572000 0x555555572000 2 0x555555572004 2 0x555555572008 2
+\end{lstlisting}
+Examples 2 to 4 change the array size, alignment and fill for the initial storage of ©ia©.
+
+\item
+©S_realloc(T) ?`realloc( T * a ))©
+used to resize, realign, and fill, where the old object data is copied to the new object.
+The old object type must be the same as the new object type, since the value is used.
+Note, for ©fill©, only the extra space after copying the data from the old object is filled with the given parameter.
+For example:
+\begin{cfa}[numbers=left]
+int * i = alloc( ®5`fill® );  sout | i | *i;
+i = alloc( ®i`realloc®, ®256`align® );  sout | i | *i;
+i = alloc( ®i`realloc®, ®4096`align®, ®13`fill® );  sout | i | *i;
+\end{cfa}
+\begin{lstlisting}[numbers=left]
+0x55555556d5c0 5
+0x555555570000 5
+0x555555571000 5
+\end{lstlisting}
+Examples 2 to 3 change the alignment for the initial storage of ©i©.
+The ©13`fill© in example 3 does nothing because no extra space is added.
+
+\begin{cfa}[numbers=left]
+int * ia = alloc( 5, ®5`fill® );  for ( i; 5 ) sout | ia[i]; sout | nl;
+ia = alloc( 10, ®ia`realloc®, ®7`fill® ); for ( i; 10 ) sout | ia[i]; sout | nl;
+sout | ia; ia = alloc( 1, ®ia`realloc®, ®512`align®, ®13`fill® ); sout | ia; for ( i; 1 ) sout | ia[i]; sout | nl;;
+ia = alloc( 3, ®ia`realloc®, ®4096`align®, ®2`fill® );  sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i]; sout | nl;
+\end{cfa}
+\begin{lstlisting}[numbers=left]
+5 5 5 5 5
+5 5 5 5 5 7 7 7 7 7
+0x55555556c560 0x555555570a00 5
+0x555555571000 0x555555571000 5 0x555555571004 2 0x555555571008 2
+\end{lstlisting}
+Examples 2 to 4 change the array size, alignment and fill for the initial storage of ©ia©.
+The ©13`fill© in example 3 does nothing because no extra space is added.
+\end{itemize}
+
+\medskip
 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
 extern "C" {
-	// C unsafe allocation
-	void * malloc( size_t size );§\indexc{malloc}§
-	void * calloc( size_t dim, size_t size );§\indexc{calloc}§
-	void * realloc( void * ptr, size_t size );§\indexc{realloc}§
-	void * memalign( size_t align, size_t size );§\indexc{memalign}§
-	void * aligned_alloc( size_t align, size_t size );§\indexc{aligned_alloc}§
-	int posix_memalign( void ** ptr, size_t align, size_t size );§\indexc{posix_memalign}§
-	void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );§\indexc{cmemalign}§ // CFA
-
-	// C unsafe initialization/copy
-	void * memset( void * dest, int c, size_t size );§\indexc{memset}§
-	void * memcpy( void * dest, const void * src, size_t size );§\indexc{memcpy}§
-}
-
-void * realloc( void * oaddr, size_t nalign, size_t size ); // CFA heap
-
-forall( dtype T | sized(T) ) {
-	// §\CFA§ safe equivalents, i.e., implicit size specification
-	T * malloc( void );
-	T * calloc( size_t dim );
-	T * realloc( T * ptr, size_t size );
-	T * memalign( size_t align );
-	T * cmemalign( size_t align, size_t dim  );
-	T * aligned_alloc( size_t align );
-	int posix_memalign( T ** ptr, size_t align );
+	// New allocation operations.
+	void * aalloc( size_t dim, size_t elemSize );§\indexc{aalloc}§
+	void * resize( void * oaddr, size_t size );§\indexc{resize}§
+	void * amemalign( size_t align, size_t dim, size_t elemSize );§\indexc{amemalign}§
+	void * cmemalign( size_t align, size_t dim, size_t elemSize );§\indexc{cmemalign}§
+	size_t malloc_alignment( void * addr );§\indexc{malloc_alignment}§
+	bool malloc_zero_fill( void * addr );§\indexc{malloc_zero_fill}§
+	size_t malloc_size( void * addr );§\indexc{malloc_size}§
+	int malloc_stats_fd( int fd );§\indexc{malloc_stats_fd}§
+	size_t malloc_expansion();§\indexc{malloc_expansion}§ $\C{// heap expansion size (bytes)}$
+	size_t malloc_mmap_start();§\indexc{malloc_mmap_start}§ $\C{// crossover allocation size from sbrk to mmap}$
+	size_t malloc_unfreed();§\indexc{malloc_unfreed()}§	$\C{// heap unfreed size (bytes)}$
+	void malloc_stats_clear();§\indexc{malloc_stats_clear}§	$\C{// clear heap statistics}$
+}
+
+// New allocation operations.
+void * resize( void * oaddr, size_t alignment, size_t size );
+void * realloc( void * oaddr, size_t alignment, size_t size );
+void * reallocarray( void * oaddr, size_t nalign, size_t dim, size_t elemSize );
+
+forall( T & | sized(T) ) {
+	// §\CFA§ safe equivalents, i.e., implicit size specification, eliminate return-type cast
+	T * malloc( void );§\indexc{malloc}§
+	T * aalloc( size_t dim );§\indexc{aalloc}§
+	T * calloc( size_t dim );§\indexc{calloc}§
+	T * resize( T * ptr, size_t size );§\indexc{resize}§
+	T * realloc( T * ptr, size_t size );§\indexc{realloc}§
+	T * reallocarray( T * ptr, size_t dim );§\indexc{reallocarray}§
+	T * memalign( size_t align );§\indexc{memalign}§
+	T * amemalign( size_t align, size_t dim );§\indexc{amemalign}§
+	T * cmemalign( size_t align, size_t dim );§\indexc{aalloc}§
+	T * aligned_alloc( size_t align );§\indexc{aligned_alloc}§
+	int posix_memalign( T ** ptr, size_t align );§\indexc{posix_memalign}§
+	T * valloc( void );§\indexc{valloc}§
+	T * pvalloc( void );§\indexc{pvalloc}§
 
 	// §\CFA§ safe general allocation, fill, resize, alignment, array
-	T * alloc( void );§\indexc{alloc}§					§\C[3.5in]{// variable, T size}§
-	T * alloc( size_t dim );							§\C{// array[dim], T size elements}§
-	T * alloc( T ptr[], size_t dim );					§\C{// realloc array[dim], T size elements}§
-
-	T * alloc_set( char fill );§\indexc{alloc_set}§		§\C{// variable, T size, fill bytes with value}§
-	T * alloc_set( T fill );							§\C{// variable, T size, fill with value}§
-	T * alloc_set( size_t dim, char fill );				§\C{// array[dim], T size elements, fill bytes with value}§
-	T * alloc_set( size_t dim, T fill );				§\C{// array[dim], T size elements, fill elements with value}§
-	T * alloc_set( size_t dim, const T fill[] );		§\C{// array[dim], T size elements, fill elements with array}§
-	T * alloc_set( T ptr[], size_t dim, char fill );	§\C{// realloc array[dim], T size elements, fill bytes with value}§
-
-	T * alloc_align( size_t align );					§\C{// aligned variable, T size}§
-	T * alloc_align( size_t align, size_t dim );		§\C{// aligned array[dim], T size elements}§
-	T * alloc_align( T ptr[], size_t align );			§\C{// realloc new aligned array}§
-	T * alloc_align( T ptr[], size_t align, size_t dim ); §\C{// realloc new aligned array[dim]}§
-
-	T * alloc_align_set( size_t align, char fill );		§\C{// aligned variable, T size, fill bytes with value}§
-	T * alloc_align_set( size_t align, T fill );		§\C{// aligned variable, T size, fill with value}§
-	T * alloc_align_set( size_t align, size_t dim, char fill ); §\C{// aligned array[dim], T size elements, fill bytes with value}§
-	T * alloc_align_set( size_t align, size_t dim, T fill ); §\C{// aligned array[dim], T size elements, fill elements with value}§
-	T * alloc_align_set( size_t align, size_t dim, const T fill[] ); §\C{// aligned array[dim], T size elements, fill elements with array}§
-	T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); §\C{// realloc new aligned array[dim], fill new bytes with value}§
+	T * alloc( ... );§\indexc{alloc}§					§\C{// variable, T size}§
+	T * alloc( size_t dim, ... );
+	T_align ?`align( size_t alignment );§\indexc{align}§
+	S_fill(T) ?`fill( /* various types */ );§\indexc{fill}§
+	S_resize(T) ?`resize( void * oaddr );§\indexc{resize}§
+	S_realloc(T) ?`realloc( T * a ));§\indexc{realloc}§
 
 	// §\CFA§ safe initialization/copy, i.e., implicit size specification
@@ -8146,14 +8451,20 @@
 
 // §\CFA§ allocation/deallocation and constructor/destructor, non-array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );§\indexc{new}§
-forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );§\indexc{delete}§
-forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } )
-  void delete( T * ptr, Params rest );
+forall( T &, TT ... ) void free( T * ptr, ... ); 
+
+forall( T & | sized(T), Params ... | { void ?{}( T &, Params ); } )
+T * new( Params p );§\indexc{new}§
+forall( T & | { void ^?{}( T & ); } )
+void delete( T * ptr );§\indexc{delete}§
+forall( T &, Params ... | { void ^?{}( T & ); void delete( Params ); } )
+void delete( T * ptr, Params rest );
 
 // §\CFA§ allocation/deallocation and constructor/destructor, array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );§\indexc{anew}§
-forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );§\indexc{adelete}§
-forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } )
-  void adelete( size_t dim, T arr[], Params rest );
+forall( T & | sized(T), Params ... | { void ?{}( T &, Params ); } )
+T * anew( size_t dim, Params p );§\indexc{anew}§
+forall( T & | sized(T) | { void ^?{}( T & ); } )
+void adelete( T arr[] );§\indexc{adelete}§
+forall( T & | sized(T) | { void ^?{}( T & ); }, Params ... | { void adelete( Params ); } )
+void adelete( T arr[], Params rest );
 \end{cfa}
 
@@ -9290,6 +9601,6 @@
 Int sqrt( Int oper );
 
-forall( dtype istype | istream( istype ) ) istype * ?|?( istype * is, Int * mp );  §\C{// I/O}§
-forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp );
+forall( istype & | istream( istype ) ) istype * ?|?( istype * is, Int * mp );  §\C{// I/O}§
+forall( ostype & | ostream( ostype ) ) ostype * ?|?( ostype * os, Int mp );
 \end{cfa}
 \VRef[Figure]{f:MultiPrecisionFactorials} shows \CFA and C factorial programs using the GMP interfaces.
@@ -9299,6 +9610,20 @@
 \begin{cquote}
 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}|@{\hspace{\parindentlnth}}l@{}}
-\multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{C}}	& \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{\CFA}}	\\
+\multicolumn{1}{@{}c|@{\hspace{\parindentlnth}}}{\textbf{\CFA}}	& \multicolumn{1}{@{\hspace{\parindentlnth}}c@{}}{\textbf{C}}	\\
 \hline
+\begin{cfa}
+#include <gmp.hfa>§\indexc{gmp}§
+int main( void ) {
+	sout | "Factorial Numbers";
+	®Int® fact = 1;
+
+	sout | 0 | fact;
+	for ( i; 40 ) {
+		fact *= i;
+		sout | i | fact;
+	}
+}
+\end{cfa}
+&
 \begin{cfa}
 #include <gmp.h>§\indexc{gmp.h}§
@@ -9311,18 +9636,4 @@
 		®mpz_mul_ui®( fact, fact, i );
 		®gmp_printf®( "%d %Zd\n", i, fact );
-	}
-}
-\end{cfa}
-&
-\begin{cfa}
-#include <gmp.hfa>§\indexc{gmp}§
-int main( void ) {
-	sout | "Factorial Numbers";
-	Int fact = 1;
-
-	sout | 0 | fact;
-	for ( i; 40 ) {
-		fact *= i;
-		sout | i | fact;
 	}
 }
@@ -9419,6 +9730,6 @@
 Rational narrow( double f, long int md );
 
-forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, Rational * ); // I/O
-forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, Rational );
+forall( istype & | istream( istype ) ) istype * ?|?( istype *, Rational * ); // I/O
+forall( ostype & | ostream( ostype ) ) ostype * ?|?( ostype *, Rational );
 \end{cfa}
 
@@ -9440,4 +9751,22 @@
 \end{document}
 
+From: Michael Leslie Brooks <mlbrooks@uwaterloo.ca>
+To: Peter Buhr <pabuhr@uwaterloo.ca>,
+        Andrew James Beach
+	<ajbeach@uwaterloo.ca>,
+        Fangren Yu <f37yu@uwaterloo.ca>, Jiada Liang
+	<j82liang@uwaterloo.ca>
+Subject: The White House on Memory-Safe programming
+Date: Mon, 4 Mar 2024 16:49:53 +0000
+
+I heard tell of this announcement last night.  Haven't read the actual report yet.
+
+Most mainstream article I can find:  https://me.pcmag.com/en/security/22413/white-house-to-developers-using-c-or-c-invites-cybersecurity-risks
+Less fluffy summary:  https://www.developer-tech.com/news/2024/feb/27/white-house-urges-adoption-memory-safe-programming-languages/
+Horse's Mouth:  https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf
+"This report focuses on the programming language as a primary building block, and explores hardware architecture and formal methods as complementary approaches"
+
+A contrary analysis:  https://hackaday.com/2024/02/29/the-white-house-memory-safety-appeal-is-a-security-red-herring/
+
 % Local Variables: %
 % tab-width: 4 %
