Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/refrat/refrat.tex

    ra752883 r90c3b1c  
    1717\usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}
    1818\usepackage{breakurl}
    19 \renewcommand{\UrlFont}{\small\sf}
     19\urlstyle{sf}
    2020
    2121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    2323% Names used in the document.
    2424
    25 \newcommand{\CFA}{C$\forall$\xspace}    % set language symbolic name
    26 \newcommand{\CFL}{Cforall\xspace}               % set language text name
     25\newcommand{\CFA}{Cforall\xspace}               % set language text name
     26\newcommand{\CFAA}{C$\forall$\xspace}   % set language symbolic name
    2727\newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name
    2828\def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name)
     
    3333
    3434\makeatletter
    35 % allow escape sequence in lstinline
    36 %\usepackage{etoolbox}
    37 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}}
    38 
    39 \renewcommand\small{%
    40    \@setfontsize\small{8.5}{11}%
    41    \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt
    42    \abovedisplayshortskip \z@ \@plus 2pt
    43    \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt
    44    \def\@listi{\leftmargin\leftmargini
    45                \topsep 4pt \@plus 2pt \@minus 2pt
    46                \parsep 2pt \@pluspt \@minuspt
    47                \itemsep \parsep}%
    48    \belowdisplayskip \abovedisplayskip
    49 }
    50 \usepackage{relsize}            % must be after change to small
    51 
    5235\renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}}
    5336\renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}}
     
    7659\renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}}
    7760\renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
    78 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
     61\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
    7962\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}}
    8063
    81 % index macros
    8264\newcommand{\italic}[1]{\emph{\hyperpage{#1}}}
    8365\newcommand{\definition}[1]{\textbf{\hyperpage{#1}}}
     
    11597
    11698% blocks and titles
     99\newcommand{\define}[1]{\emph{#1\/}\index{#1}}
    117100\newenvironment{rationale}{%
    118101  \begin{quotation}\noindent$\Box$\enspace
     
    120103  \hfill\enspace$\Box$\end{quotation}
    121104}%
    122 \newcommand{\define}[1]{\emph{#1\/}\index{#1}}
    123105\newcommand{\rewrite}{\(\Rightarrow\)}
    124106\newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent}
     
    149131\newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}}
    150132
    151 % CFA based on ANSI C
     133% adjust listings macros
    152134\lstdefinelanguage{CFA}[ANSI]{C}%
    153 {morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,trait,disable,dtype,enable,
    154         fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,otype,restrict,_Static_assert,
    155         _Thread_local,throw,throwResume,try,},
     135{morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,context,disable,dtype,enable,
     136        fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,restrict,_Static_assert,
     137        _Thread_local,throw,throwResume,try,type,},
    156138}%
    157139
     
    159141language=CFA,
    160142columns=flexible,
    161 basicstyle=\sf\relsize{-1},
     143basicstyle=\sf\small,
    162144tabsize=4,
    163145xleftmargin=\parindent,
    164146escapechar=@,
    165147keepspaces=true,
    166 showstringspaces=false,
    167 showlines=true,
     148%showtabs=true,
     149%tab=\rightarrowfill,
    168150}%
    169151
     
    192174
    193175\title{\Huge
    194 \CFA (\CFL) Reference Manual and Rationale
     176\CFA (\CFAA) Reference Manual and Rationale
    195177}% title
    196178\author{\huge
     
    298280An instantiation of the generic type is written by specifying the type parameters in parentheses after the name of the generic type generator:
    299281\begin{lstlisting}
    300 forall( otype T | sumable( T ) ) struct pair {
     282forall( type T | sumable( T ) ) struct pair {
    301283        T x;
    302284        T y;
     
    310292Polymorphic functions may have generic types as parameters, and those generic types may use type parameters of the polymorphic function as type parameters of the generic type:
    311293\begin{lstlisting}
    312 forall( otype T ) void swap( pair(T) *p ) {
     294forall( type T ) void swap( pair(T) *p ) {
    313295        T z = p->x;
    314296        p->x = p->y;
     
    320302\subsubsection{Constraints}
    321303
    322 To avoid unduly constraining implementors, the generic type generator definition must be visible at any point where it is instantiated.
    323 Forward declarations of generic type generators are not forbidden, but the definition must be visible to instantiate the generic type.  Equivalently, instantiations of generic types are not allowed to be incomplete types.
     304To avoid unduly constraining implementors, the generic type generator definition must be visible at any point where it is instantiated.  Forward declarations of generic type generators are not forbidden, but the definition must be visible to instantiate the generic type.  Equivalently, instantiations of generic types are not allowed to be incomplete types.
    324305
    325306\examples
    326307\begin{lstlisting}
    327 forall( otype T ) struct A;
    328 
    329 forall( otype T ) struct B {
     308forall( type T ) struct A;
     309
     310forall( type T ) struct B {
    330311        A(T) *a;                        // legal, but cannot instantiate B(T)
    331312};
     
    333314B(T) x;                                 // illegal, *x.a is of an incomplete generic type
    334315 
    335 forall( otype T ) struct A {
     316forall( type T ) struct A {
    336317        B( T ) *b;
    337318};
     
    340321
    341322// box.h:
    342         forall( otype T ) struct box;
    343         forall( otype T ) box( T ) *make_box( T );
    344         forall( otype T ) void use_box( box( T ) *b );
     323        forall( type T ) struct box;
     324        forall( type T ) box( T ) *make_box( T );
     325        forall( type T ) void use_box( box( T ) *b );
    345326       
    346327// main.c:
     
    429410
    430411\subsubsection{Specialization}
    431 A function or value whose type is polymorphic may be implicitly converted to one whose type is \Index{less polymorphic} by binding values to one or more of its \Index{inferred parameter}.
     412A function or value whose type is polymorphic may be implicitly converted to one whose type is
     413\Index{less polymorphic} by binding values to one or more of its \Index{inferred parameter}.
    432414Any value that is legal for the inferred parameter may be used, including other inferred parameters.
    433415
    434 If, after the inferred parameter binding, an \Index{assertion parameter} has no inferred parameters in its type, then an object or function must be visible at the point of the specialization that has the same identifier as the assertion parameter and has a type that is compatible\index{compatible type} with or can be specialized to the type of the assertion parameter.
    435 The assertion parameter is bound to that object or function.
     416If, after the inferred parameter binding, an \Index{assertion parameter} has no inferred parameters in its type, then an object or function must be visible at the point of the specialization that has the same identifier as the assertion parameter and has a type that is compatible\index{compatible
     417  type} with or can be specialized to the type of the assertion parameter.  The assertion parameter is bound to that object or function.
    436418
    437419The type of the specialization is the type of the original with the bound inferred parameters and the bound assertion parameters replaced by their bound values.
     
    440422The type
    441423\begin{lstlisting}
    442 forall( otype T, otype U ) void (*)( T, U );
     424forall( type T, type U ) void (*)( T, U );
    443425\end{lstlisting}
    444426can be specialized to (among other things)
    445427\begin{lstlisting}
    446 forall( otype T ) void (*)( T, T );             // U bound to T
    447 forall( otype T ) void (*)( T, real );  // U bound to real
    448 forall( otype U ) void (*)( real, U );  // T bound to real
     428forall( type T ) void (*)( T, T );              // U bound to T
     429forall( type T ) void (*)( T, real );   // U bound to real
     430forall( type U ) void (*)( real, U );   // T bound to real
    449431void f( real, real );                                   // both bound to real
    450432\end{lstlisting}
     
    452434The type
    453435\begin{lstlisting}
    454 forall( otype T | T ?+?( T, T ) ) T (*)( T );
     436forall( type T | T ?+?( T, T ) ) T (*)( T );
    455437\end{lstlisting}
    456438can be specialized to (among other things)
     
    512494If \lstinline$int$ can represent all the values of \lstinline$unsigned short$, then the cost of an implicit conversion from \lstinline$unsigned short$ to \lstinline$unsigned$ is 2:
    513495\lstinline$unsigned short$ to \lstinline$int$ to \lstinline$unsigned$.
    514 Otherwise, \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1.
     496Otherwise,
     497\lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1.
    515498
    516499\item
     
    525508        \rhs \lstinline$forall$
    526509        \rhs \lstinline$lvalue$
    527         \rhs \lstinline$trait$
     510        \rhs \lstinline$context$
    528511        \rhs \lstinline$dtype$
    529512        \rhs \lstinline$ftype$
     
    556539A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type.
    557540
    558 In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to 0 as a special case.
     541In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to
     5420 as a special case.
    559543However, user-defined arithmetic types often need the equivalent of a 1 or 0 for their functions or operators, polymorphic functions often need 0 and 1 constants of a type matching their polymorphic parameters, and user-defined pointer-like types may need a null value.
    560544Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline$_Bool$.
     
    852836\predefined
    853837\begin{lstlisting}
    854 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@
    855 forall( otype T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );
    856 forall( otype T ) lvalue const T ?[?]( const T *, ptrdiff_t );
    857 forall( otype T ) lvalue restrict T ?[?]( restrict T *, ptrdiff_t );
    858 forall( otype T ) lvalue volatile T ?[?]( volatile T *, ptrdiff_t );
    859 forall( otype T ) lvalue _Atomic const T ?[?]( _Atomic const T *, ptrdiff_t );
    860 forall( otype T ) lvalue _Atomic restrict T ?[?]( _Atomic restrict T *, ptrdiff_t );
    861 forall( otype T ) lvalue _Atomic volatile T ?[?]( _Atomic volatile T *, ptrdiff_t );
    862 forall( otype T ) lvalue const restrict T ?[?]( const restrict T *, ptrdiff_t );
    863 forall( otype T ) lvalue const volatile T ?[?]( const volatile T *, ptrdiff_t );
    864 forall( otype T ) lvalue restrict volatile T ?[?]( restrict volatile T *, ptrdiff_t );
    865 forall( otype T ) lvalue _Atomic const restrict T ?[?]( _Atomic const restrict T *, ptrdiff_t );
    866 forall( otype T ) lvalue _Atomic const volatile T ?[?]( _Atomic const volatile T *, ptrdiff_t );
    867 forall( otype T ) lvalue _Atomic restrict volatile T ?[?]( _Atomic restrict volatile T *, ptrdiff_t );
    868 forall( otype T ) lvalue const restrict volatile T ?[?]( const restrict volatile T *, ptrdiff_t );
    869 forall( otype T ) lvalue _Atomic const restrict volatile T ?[?]( _Atomic const restrict volatile T *, ptrdiff_t );
     838forall( type T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@
     839forall( type T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );
     840forall( type T ) lvalue const T ?[?]( const T *, ptrdiff_t );
     841forall( type T ) lvalue restrict T ?[?]( restrict T *, ptrdiff_t );
     842forall( type T ) lvalue volatile T ?[?]( volatile T *, ptrdiff_t );
     843forall( type T ) lvalue _Atomic const T ?[?]( _Atomic const T *, ptrdiff_t );
     844forall( type T ) lvalue _Atomic restrict T ?[?]( _Atomic restrict T *, ptrdiff_t );
     845forall( type T ) lvalue _Atomic volatile T ?[?]( _Atomic volatile T *, ptrdiff_t );
     846forall( type T ) lvalue const restrict T ?[?]( const restrict T *, ptrdiff_t );
     847forall( type T ) lvalue const volatile T ?[?]( const volatile T *, ptrdiff_t );
     848forall( type T ) lvalue restrict volatile T ?[?]( restrict volatile T *, ptrdiff_t );
     849forall( type T ) lvalue _Atomic const restrict T ?[?]( _Atomic const restrict T *, ptrdiff_t );
     850forall( type T ) lvalue _Atomic const volatile T ?[?]( _Atomic const volatile T *, ptrdiff_t );
     851forall( type T ) lvalue _Atomic restrict volatile T ?[?]( _Atomic restrict volatile T *, ptrdiff_t );
     852forall( type T ) lvalue const restrict volatile T ?[?]( const restrict volatile T *, ptrdiff_t );
     853forall( type T ) lvalue _Atomic const restrict volatile T ?[?]( _Atomic const restrict volatile T *, ptrdiff_t );
    870854\end{lstlisting}
    871855\semantics
     
    930914\begin{rationale}
    931915One desirable property of a polymorphic programming language is \define{generalizability}: the ability to replace an abstraction with a more general but equivalent abstraction without requiring changes in any of the uses of the original\cite{Cormack90}.
    932 For instance, it should be possible to replace a function ``\lstinline$int f( int );$'' with ``\lstinline$forall( otype T ) T f( T );$'' without affecting any calls of \lstinline$f$.
     916For instance, it should be possible to replace a function ``\lstinline$int f( int );$'' with ``\lstinline$forall( type T ) T f( T );$'' without affecting any calls of \lstinline$f$.
    933917
    934918\CFA\index{deficiencies!generalizability} does not fully possess this property, because
     
    944928f = g( d, f );          // (3) (unsafe conversion to float)
    945929\end{lstlisting}
    946 If \lstinline$g$ was replaced by ``\lstinline$forall( otype T ) T g( T, T );$'', the first and second calls would be unaffected, but the third would change: \lstinline$f$ would be converted to
     930If \lstinline$g$ was replaced by ``\lstinline$forall( type T ) T g( T, T );$'', the first and second calls would be unaffected, but the third would change: \lstinline$f$ would be converted to
    947931\lstinline$double$, and the result would be a \lstinline$double$.
    948932
    949933Another example is the function ``\lstinline$void h( int *);$''.
    950934This function can be passed a
    951 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( otype T ) void h( T *);$'' can not.
     935\lstinline$void *$ argument, but the generalization ``\lstinline$forall( type T ) void h( T *);$'' can not.
    952936In this case, \lstinline$void$ is not a valid value for \lstinline$T$ because it is not an object type.
    953937If unsafe conversions were allowed, \lstinline$T$ could be inferred to be \emph{any} object type, which is undesirable.
     
    957941A function called ``\lstinline$?()$'' might be part of a numerical differentiation package.
    958942\begin{lstlisting}
    959 extern otype Derivative;
     943extern type Derivative;
    960944extern double ?()( Derivative, double );
    961945extern Derivative derivative_of( double (*f)( double ) );
     
    978962
    979963\begin{lstlisting}
    980 forall( otype T ) T h( T );
     964forall( type T ) T h( T );
    981965double d = h( 1.5 );
    982966\end{lstlisting}
     
    985969
    986970\begin{lstlisting}
    987 forall( otype T, otype U ) void g( T, U );      // (4)
    988 forall( otype T ) void g( T, T );                       // (5)
    989 forall( otype T ) void g( T, long );                    // (6)
     971forall( type T, type U ) void g( T, U );        // (4)
     972forall( type T ) void g( T, T );                        // (5)
     973forall( type T ) void g( T, long );                     // (6)
    990974void g( long, long );                                           // (7)
    991975double d;
     
    1007991The fourth call has no interpretation for (5), because its arguments must have compatible type. (4) is chosen because it does not involve unsafe conversions.
    1008992\begin{lstlisting}
    1009 forall( otype T ) T min( T, T );
     993forall( type T ) T min( T, T );
    1010994double max( double, double );
    1011 trait min_max( T ) {@\impl{min_max}@
     995context min_max( T ) {@\impl{min_max}@
    1012996        T min( T, T );
    1013997        T max( T, T );
    1014998}
    1015 forall( otype U | min_max( U ) ) void shuffle( U, U );
     999forall( type U | min_max( U ) ) void shuffle( U, U );
    10161000shuffle( 9, 10 );
    10171001\end{lstlisting}
     
    10631047long double ?++( volatile long double * ), ?++( _Atomic volatile long double * );
    10641048
    1065 forall( otype T ) T * ?++( T * restrict volatile * ), * ?++( T * _Atomic restrict volatile * );
    1066 forall( otype T ) _Atomic T * ?++( _Atomic T * restrict volatile * ), * ?++( _Atomic T * _Atomic restrict volatile * );
    1067 forall( otype T ) const T * ?++( const T * restrict volatile * ), * ?++( const T * _Atomic restrict volatile * );
    1068 forall( otype T ) volatile T * ?++( volatile T * restrict volatile * ), * ?++( volatile T * _Atomic restrict volatile * );
    1069 forall( otype T ) restrict T * ?++( restrict T * restrict volatile * ), * ?++( restrict T * _Atomic restrict volatile * );
    1070 forall( otype T ) _Atomic const T * ?++( _Atomic const T * restrict volatile * ),
     1049forall( type T ) T * ?++( T * restrict volatile * ), * ?++( T * _Atomic restrict volatile * );
     1050forall( type T ) _Atomic T * ?++( _Atomic T * restrict volatile * ), * ?++( _Atomic T * _Atomic restrict volatile * );
     1051forall( type T ) const T * ?++( const T * restrict volatile * ), * ?++( const T * _Atomic restrict volatile * );
     1052forall( type T ) volatile T * ?++( volatile T * restrict volatile * ), * ?++( volatile T * _Atomic restrict volatile * );
     1053forall( type T ) restrict T * ?++( restrict T * restrict volatile * ), * ?++( restrict T * _Atomic restrict volatile * );
     1054forall( type T ) _Atomic const T * ?++( _Atomic const T * restrict volatile * ),
    10711055        * ?++( _Atomic const T * _Atomic restrict volatile * );
    1072 forall( otype T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ),
     1056forall( type T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ),
    10731057        * ?++( _Atomic restrict T * _Atomic restrict volatile * );
    1074 forall( otype T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ),
     1058forall( type T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ),
    10751059        * ?++( _Atomic volatile T * _Atomic restrict volatile * );
    1076 forall( otype T ) const restrict T * ?++( const restrict T * restrict volatile * ),
     1060forall( type T ) const restrict T * ?++( const restrict T * restrict volatile * ),
    10771061        * ?++( const restrict T * _Atomic restrict volatile * );
    1078 forall( otype T ) const volatile T * ?++( const volatile T * restrict volatile * ),
     1062forall( type T ) const volatile T * ?++( const volatile T * restrict volatile * ),
    10791063        * ?++( const volatile T * _Atomic restrict volatile * );
    1080 forall( otype T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ),
     1064forall( type T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ),
    10811065        * ?++( restrict volatile T * _Atomic restrict volatile * );
    1082 forall( otype T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ),
     1066forall( type T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ),
    10831067        * ?++( _Atomic const restrict T * _Atomic restrict volatile * );
    1084 forall( otype T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ),
     1068forall( type T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ),
    10851069        * ?++( _Atomic const volatile T * _Atomic restrict volatile * );
    1086 forall( otype T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ),
     1070forall( type T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ),
    10871071        * ?++( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1088 forall( otype T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ),
     1072forall( type T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ),
    10891073        * ?++( const restrict volatile T * _Atomic restrict volatile * );
    1090 forall( otype T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ),
     1074forall( type T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ),
    10911075        * ?++( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    10921076
     
    11071091long double ?--( volatile long double * ), ?--( _Atomic volatile long double * );
    11081092
    1109 forall( otype T ) T * ?--( T * restrict volatile * ), * ?--( T * _Atomic restrict volatile * );
    1110 forall( otype T ) _Atomic T * ?--( _Atomic T * restrict volatile * ), * ?--( _Atomic T * _Atomic restrict volatile * );
    1111 forall( otype T ) const T * ?--( const T * restrict volatile * ), * ?--( const T * _Atomic restrict volatile * );
    1112 forall( otype T ) volatile T * ?--( volatile T * restrict volatile * ), * ?--( volatile T * _Atomic restrict volatile * );
    1113 forall( otype T ) restrict T * ?--( restrict T * restrict volatile * ), * ?--( restrict T * _Atomic restrict volatile * );
    1114 forall( otype T ) _Atomic const T * ?--( _Atomic const T * restrict volatile * ),
     1093forall( type T ) T * ?--( T * restrict volatile * ), * ?--( T * _Atomic restrict volatile * );
     1094forall( type T ) _Atomic T * ?--( _Atomic T * restrict volatile * ), * ?--( _Atomic T * _Atomic restrict volatile * );
     1095forall( type T ) const T * ?--( const T * restrict volatile * ), * ?--( const T * _Atomic restrict volatile * );
     1096forall( type T ) volatile T * ?--( volatile T * restrict volatile * ), * ?--( volatile T * _Atomic restrict volatile * );
     1097forall( type T ) restrict T * ?--( restrict T * restrict volatile * ), * ?--( restrict T * _Atomic restrict volatile * );
     1098forall( type T ) _Atomic const T * ?--( _Atomic const T * restrict volatile * ),
    11151099        * ?--( _Atomic const T * _Atomic restrict volatile * );
    1116 forall( otype T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ),
     1100forall( type T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ),
    11171101        * ?--( _Atomic restrict T * _Atomic restrict volatile * );
    1118 forall( otype T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ),
     1102forall( type T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ),
    11191103        * ?--( _Atomic volatile T * _Atomic restrict volatile * );
    1120 forall( otype T ) const restrict T * ?--( const restrict T * restrict volatile * ),
     1104forall( type T ) const restrict T * ?--( const restrict T * restrict volatile * ),
    11211105        * ?--( const restrict T * _Atomic restrict volatile * );
    1122 forall( otype T ) const volatile T * ?--( const volatile T * restrict volatile * ),
     1106forall( type T ) const volatile T * ?--( const volatile T * restrict volatile * ),
    11231107        * ?--( const volatile T * _Atomic restrict volatile * );
    1124 forall( otype T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ),
     1108forall( type T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ),
    11251109        * ?--( restrict volatile T * _Atomic restrict volatile * );
    1126 forall( otype T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ),
     1110forall( type T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ),
    11271111        * ?--( _Atomic const restrict T * _Atomic restrict volatile * );
    1128 forall( otype T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ),
     1112forall( type T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ),
    11291113        * ?--( _Atomic const volatile T * _Atomic restrict volatile * );
    1130 forall( otype T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ),
     1114forall( type T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ),
    11311115        * ?--( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1132 forall( otype T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ),
     1116forall( type T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ),
    11331117        * ?--( const restrict volatile T * _Atomic restrict volatile * );
    1134 forall( otype T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ),
     1118forall( type T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ),
    11351119        * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    11361120\end{lstlisting}
     
    12111195The expression would be valid if \lstinline$?++$ were declared by
    12121196\begin{lstlisting}
    1213 forall( otype T ) T * ?++( T * * );
     1197forall( type T ) T * ?++( T * * );
    12141198\end{lstlisting} with \lstinline$T$ inferred to be \lstinline$char$.
    12151199
     
    12191203Hence the actual predefined function is
    12201204\begin{lstlisting}
    1221 forall( otype T ) T * ?++( T * restrict volatile * );
     1205forall( type T ) T * ?++( T * restrict volatile * );
    12221206\end{lstlisting} which also accepts a \lstinline$char * *$ argument, because of the safe conversions that add
    12231207\lstinline$volatile$ and \lstinline$restrict$ qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.)
     
    12331217\lstinline$char const volatile *$, so a new overloading is needed:
    12341218\begin{lstlisting}
    1235 forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * );
     1219forall( type T ) T const volatile * ?++( T const volatile *restrict volatile * );
    12361220\end{lstlisting}
    12371221One overloading is needed for each combination of qualifiers in the pointed-at type\index{deficiencies!pointers to qualified types}.
     
    12411225The \lstinline$restrict$ qualifier is handled just like \lstinline$const$ and \lstinline$volatile$ in the previous case:
    12421226\begin{lstlisting}
    1243 forall( otype T ) T restrict * ?++( T restrict *restrict volatile * );
     1227forall( type T ) T restrict * ?++( T restrict *restrict volatile * );
    12441228\end{lstlisting} with \lstinline$T$ inferred to be \lstinline$float *$.
    12451229This looks odd, because {\c11} contains a constraint that requires restrict-qualified types to be pointer-to-object types, and \lstinline$T$ is not syntactically a pointer type. \CFA loosens the constraint.
     
    12991283long double ++?( volatile long double * ), ++?( _Atomic volatile long double * );
    13001284
    1301 forall( otype T ) T * ++?( T * restrict volatile * ), * ++?( T * _Atomic restrict volatile * );
    1302 forall( otype T ) _Atomic T * ++?( _Atomic T * restrict volatile * ), * ++?( _Atomic T * _Atomic restrict volatile * );
    1303 forall( otype T ) const T * ++?( const T * restrict volatile * ), * ++?( const T * _Atomic restrict volatile * );
    1304 forall( otype T ) volatile T * ++?( volatile T * restrict volatile * ), * ++?( volatile T * _Atomic restrict volatile * );
    1305 forall( otype T ) restrict T * ++?( restrict T * restrict volatile * ), * ++?( restrict T * _Atomic restrict volatile * );
    1306 forall( otype T ) _Atomic const T * ++?( _Atomic const T * restrict volatile * ),
     1285forall( type T ) T * ++?( T * restrict volatile * ), * ++?( T * _Atomic restrict volatile * );
     1286forall( type T ) _Atomic T * ++?( _Atomic T * restrict volatile * ), * ++?( _Atomic T * _Atomic restrict volatile * );
     1287forall( type T ) const T * ++?( const T * restrict volatile * ), * ++?( const T * _Atomic restrict volatile * );
     1288forall( type T ) volatile T * ++?( volatile T * restrict volatile * ), * ++?( volatile T * _Atomic restrict volatile * );
     1289forall( type T ) restrict T * ++?( restrict T * restrict volatile * ), * ++?( restrict T * _Atomic restrict volatile * );
     1290forall( type T ) _Atomic const T * ++?( _Atomic const T * restrict volatile * ),
    13071291        * ++?( _Atomic const T * _Atomic restrict volatile * );
    1308 forall( otype T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ),
     1292forall( type T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ),
    13091293        * ++?( _Atomic volatile T * _Atomic restrict volatile * );
    1310 forall( otype T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ),
     1294forall( type T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ),
    13111295        * ++?( _Atomic restrict T * _Atomic restrict volatile * );
    1312 forall( otype T ) const volatile T * ++?( const volatile T * restrict volatile * ),
     1296forall( type T ) const volatile T * ++?( const volatile T * restrict volatile * ),
    13131297        * ++?( const volatile T * _Atomic restrict volatile * );
    1314 forall( otype T ) const restrict T * ++?( const restrict T * restrict volatile * ),
     1298forall( type T ) const restrict T * ++?( const restrict T * restrict volatile * ),
    13151299        * ++?( const restrict T * _Atomic restrict volatile * );
    1316 forall( otype T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ),
     1300forall( type T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ),
    13171301        * ++?( restrict volatile T * _Atomic restrict volatile * );
    1318 forall( otype T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ),
     1302forall( type T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ),
    13191303        * ++?( _Atomic const volatile T * _Atomic restrict volatile * );
    1320 forall( otype T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ),
     1304forall( type T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ),
    13211305        * ++?( _Atomic const restrict T * _Atomic restrict volatile * );
    1322 forall( otype T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ),
     1306forall( type T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ),
    13231307        * ++?( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1324 forall( otype T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ),
     1308forall( type T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ),
    13251309        * ++?( const restrict volatile T * _Atomic restrict volatile * );
    1326 forall( otype T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ),
     1310forall( type T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ),
    13271311        * ++?( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    13281312
     
    13431327long double --?( volatile long double * ), --?( _Atomic volatile long double * );
    13441328
    1345 forall( otype T ) T * --?( T * restrict volatile * ), * --?( T * _Atomic restrict volatile * );
    1346 forall( otype T ) _Atomic T * --?( _Atomic T * restrict volatile * ), * --?( _Atomic T * _Atomic restrict volatile * );
    1347 forall( otype T ) const T * --?( const T * restrict volatile * ), * --?( const T * _Atomic restrict volatile * );
    1348 forall( otype T ) volatile T * --?( volatile T * restrict volatile * ), * --?( volatile T * _Atomic restrict volatile * );
    1349 forall( otype T ) restrict T * --?( restrict T * restrict volatile * ), * --?( restrict T * _Atomic restrict volatile * );
    1350 forall( otype T ) _Atomic const T * --?( _Atomic const T * restrict volatile * ),
     1329forall( type T ) T * --?( T * restrict volatile * ), * --?( T * _Atomic restrict volatile * );
     1330forall( type T ) _Atomic T * --?( _Atomic T * restrict volatile * ), * --?( _Atomic T * _Atomic restrict volatile * );
     1331forall( type T ) const T * --?( const T * restrict volatile * ), * --?( const T * _Atomic restrict volatile * );
     1332forall( type T ) volatile T * --?( volatile T * restrict volatile * ), * --?( volatile T * _Atomic restrict volatile * );
     1333forall( type T ) restrict T * --?( restrict T * restrict volatile * ), * --?( restrict T * _Atomic restrict volatile * );
     1334forall( type T ) _Atomic const T * --?( _Atomic const T * restrict volatile * ),
    13511335        * --?( _Atomic const T * _Atomic restrict volatile * );
    1352 forall( otype T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ),
     1336forall( type T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ),
    13531337        * --?( _Atomic volatile T * _Atomic restrict volatile * );
    1354 forall( otype T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ),
     1338forall( type T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ),
    13551339        * --?( _Atomic restrict T * _Atomic restrict volatile * );
    1356 forall( otype T ) const volatile T * --?( const volatile T * restrict volatile * ),
     1340forall( type T ) const volatile T * --?( const volatile T * restrict volatile * ),
    13571341        * --?( const volatile T * _Atomic restrict volatile * );
    1358 forall( otype T ) const restrict T * --?( const restrict T * restrict volatile * ),
     1342forall( type T ) const restrict T * --?( const restrict T * restrict volatile * ),
    13591343        * --?( const restrict T * _Atomic restrict volatile * );
    1360 forall( otype T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ),
     1344forall( type T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ),
    13611345        * --?( restrict volatile T * _Atomic restrict volatile * );
    1362 forall( otype T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ),
     1346forall( type T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ),
    13631347        * --?( _Atomic const volatile T * _Atomic restrict volatile * );
    1364 forall( otype T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ),
     1348forall( type T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ),
    13651349        * --?( _Atomic const restrict T * _Atomic restrict volatile * );
    1366 forall( otype T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ),
     1350forall( type T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ),
    13671351        * --?( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1368 forall( otype T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ),
     1352forall( type T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ),
    13691353        * --?( const restrict volatile T * _Atomic restrict volatile * );
    1370 forall( otype T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ),
     1354forall( type T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ),
    13711355        * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    13721356\end{lstlisting}
     
    13961380\predefined
    13971381\begin{lstlisting}
    1398 forall( otype T ) lvalue T *?( T * );
    1399 forall( otype T ) _Atomic lvalue T *?( _Atomic T * );
    1400 forall( otype T ) const lvalue T *?( const T * );
    1401 forall( otype T ) volatile lvalue T *?( volatile T * );
    1402 forall( otype T ) restrict lvalue T *?( restrict T * );
    1403 forall( otype T ) _Atomic const lvalue T *?( _Atomic const T * );
    1404 forall( otype T ) _Atomic volatile lvalue T *?( _Atomic volatile T * );
    1405 forall( otype T ) _Atomic restrict lvalue T *?( _Atomic restrict T * );
    1406 forall( otype T ) const volatile lvalue T *?( const volatile T * );
    1407 forall( otype T ) const restrict lvalue T *?( const restrict T * );
    1408 forall( otype T ) restrict volatile lvalue T *?( restrict volatile T * );
    1409 forall( otype T ) _Atomic const volatile lvalue T *?( _Atomic const volatile T * );
    1410 forall( otype T ) _Atomic const restrict lvalue T *?( _Atomic const restrict T * );
    1411 forall( otype T ) _Atomic restrict volatile lvalue T *?( _Atomic restrict volatile T * );
    1412 forall( otype T ) const restrict volatile lvalue T *?( const restrict volatile T * );
    1413 forall( otype T ) _Atomic const restrict volatile lvalue T *?( _Atomic const restrict volatile T * );
     1382forall( type T ) lvalue T *?( T * );
     1383forall( type T ) _Atomic lvalue T *?( _Atomic T * );
     1384forall( type T ) const lvalue T *?( const T * );
     1385forall( type T ) volatile lvalue T *?( volatile T * );
     1386forall( type T ) restrict lvalue T *?( restrict T * );
     1387forall( type T ) _Atomic const lvalue T *?( _Atomic const T * );
     1388forall( type T ) _Atomic volatile lvalue T *?( _Atomic volatile T * );
     1389forall( type T ) _Atomic restrict lvalue T *?( _Atomic restrict T * );
     1390forall( type T ) const volatile lvalue T *?( const volatile T * );
     1391forall( type T ) const restrict lvalue T *?( const restrict T * );
     1392forall( type T ) restrict volatile lvalue T *?( restrict volatile T * );
     1393forall( type T ) _Atomic const volatile lvalue T *?( _Atomic const volatile T * );
     1394forall( type T ) _Atomic const restrict lvalue T *?( _Atomic const restrict T * );
     1395forall( type T ) _Atomic restrict volatile lvalue T *?( _Atomic restrict volatile T * );
     1396forall( type T ) const restrict volatile lvalue T *?( const restrict volatile T * );
     1397forall( type T ) _Atomic const restrict volatile lvalue T *?( _Atomic const restrict volatile T * );
    14141398forall( ftype FT ) FT *?( FT * );
    14151399\end{lstlisting}
     
    15261510\begin{rationale}
    15271511\begin{lstlisting}
    1528 otype Pair = struct { int first, second; };
     1512type Pair = struct { int first, second; };
    15291513size_t p_size = sizeof(Pair);           // constant expression
    1530 extern otype Rational;@\use{Rational}@
     1514extern type Rational;@\use{Rational}@
    15311515size_t c_size = sizeof(Rational);       // non-constant expression
    15321516forall(type T) T f(T p1, T p2) {
     
    16521636Consider
    16531637\begin{lstlisting}
    1654 forall( otype T | T ?*?( T, T ) ) T square( T );
     1638forall( type T | T ?*?( T, T ) ) T square( T );
    16551639short s;
    16561640square( s );
     
    16631647A more troubling example is
    16641648\begin{lstlisting}
    1665 forall( otype T | ?*?( T, T ) ) T product( T[], int n );
     1649forall( type T | ?*?( T, T ) ) T product( T[], int n );
    16661650short sa[5];
    16671651product( sa, 5);
     
    17201704        ?+?( _Complex long double, _Complex long double ), ?-?( _Complex long double, _Complex long double );
    17211705
    1722 forall( otype T ) T * ?+?( T *, ptrdiff_t ), * ?+?( ptrdiff_t, T * ), * ?-?( T *, ptrdiff_t );
    1723 forall( otype T ) _Atomic T * ?+?( _Atomic T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic T * ),
     1706forall( type T ) T * ?+?( T *, ptrdiff_t ), * ?+?( ptrdiff_t, T * ), * ?-?( T *, ptrdiff_t );
     1707forall( type T ) _Atomic T * ?+?( _Atomic T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic T * ),
    17241708        * ?-?( _Atomic T *, ptrdiff_t );
    1725 forall( otype T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ),
     1709forall( type T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ),
    17261710        * ?-?( const T *, ptrdiff_t );
    1727 forall( otype T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ),
     1711forall( type T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ),
    17281712        * ?-?( restrict T *, ptrdiff_t );
    1729 forall( otype T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ),
     1713forall( type T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ),
    17301714        * ?-?( volatile T *, ptrdiff_t );
    1731 forall( otype T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ),
     1715forall( type T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ),
    17321716        * ?-?( _Atomic const T *, ptrdiff_t );
    1733 forall( otype T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ),
     1717forall( type T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ),
    17341718        * ?-?( _Atomic restrict T *, ptrdiff_t );
    1735 forall( otype T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ),
     1719forall( type T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ),
    17361720        * ?-?( _Atomic volatile T *, ptrdiff_t );
    1737 forall( otype T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ),
     1721forall( type T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ),
    17381722        * ?-?( const restrict T *, ptrdiff_t );
    1739 forall( otype T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ),
     1723forall( type T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ),
    17401724        * ?-?( const volatile T *, ptrdiff_t );
    1741 forall( otype T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ),
     1725forall( type T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ),
    17421726        * ?-?( restrict volatile T *, ptrdiff_t );
    1743 forall( otype T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ),
     1727forall( type T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ),
    17441728        * ?+?( ptrdiff_t, _Atomic const restrict T * ),
    17451729        * ?-?( _Atomic const restrict T *, ptrdiff_t );
    1746 forall( otype T ) ptrdiff_t
     1730forall( type T ) ptrdiff_t
    17471731        * ?-?( const restrict volatile T *, const restrict volatile T * ),
    17481732        * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * );
     
    20682052
    20692053\begin{lstlisting}
    2070 extern otype Rational;@\use{Rational}@
     2054extern type Rational;@\use{Rational}@
    20712055extern const Rational 0;@\use{0}@
    20722056extern int ?!=?( Rational, Rational );
     
    21112095If the second and third operands both have interpretations with non-\lstinline$void$ types, the expression is treated as if it were the call ``\lstinline$cond((a)!=0, b, c)$'', with \lstinline$cond$ declared as
    21122096\begin{lstlisting}
    2113 forall( otype T ) T cond( int, T, T );
     2097forall( type T ) T cond( int, T, T );
    21142098forall( dtype D ) void * cond( int, D *, void * ), * cond( int, void *, D * );
    21152099forall( dtype D ) _atomic void * cond(
     
    24712455\predefined
    24722456\begin{lstlisting}
    2473 forall( otype T ) T
     2457forall( type T ) T
    24742458        * ?+=?( T * restrict volatile *, ptrdiff_t ),
    24752459        * ?-=?( T * restrict volatile *, ptrdiff_t ),
    24762460        * ?+=?( T * _Atomic restrict volatile *, ptrdiff_t ),
    24772461        * ?-=?( T * _Atomic restrict volatile *, ptrdiff_t );
    2478 forall( otype T ) T _Atomic
     2462forall( type T ) T _Atomic
    24792463        * ?+=?( T _Atomic * restrict volatile *, ptrdiff_t ),
    24802464        * ?-=?( T _Atomic * restrict volatile *, ptrdiff_t ),
    24812465        * ?+=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t ),
    24822466        * ?-=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t );
    2483 forall( otype T ) T const
     2467forall( type T ) T const
    24842468        * ?+=?( T const * restrict volatile *, ptrdiff_t ),
    24852469        * ?-=?( T const * restrict volatile *, ptrdiff_t ),
    24862470        * ?+=?( T const * _Atomic restrict volatile *, ptrdiff_t ),
    24872471        * ?-=?( T const * _Atomic restrict volatile *, ptrdiff_t );
    2488 forall( otype T ) T restrict
     2472forall( type T ) T restrict
    24892473        * ?+=?( T restrict * restrict volatile *, ptrdiff_t ),
    24902474        * ?-=?( T restrict * restrict volatile *, ptrdiff_t ),
    24912475        * ?+=?( T restrict * _Atomic restrict volatile *, ptrdiff_t ),
    24922476        * ?-=?( T restrict * _Atomic restrict volatile *, ptrdiff_t );
    2493 forall( otype T ) T volatile
     2477forall( type T ) T volatile
    24942478        * ?+=?( T volatile * restrict volatile *, ptrdiff_t ),
    24952479        * ?-=?( T volatile * restrict volatile *, ptrdiff_t ),
    24962480        * ?+=?( T volatile * _Atomic restrict volatile *, ptrdiff_t ),
    24972481        * ?-=?( T volatile * _Atomic restrict volatile *, ptrdiff_t );
    2498 forall( otype T ) T _Atomic const
     2482forall( type T ) T _Atomic const
    24992483        * ?+=?( T _Atomic const restrict volatile *, ptrdiff_t ),
    25002484        * ?-=?( T _Atomic const restrict volatile *, ptrdiff_t ),
    25012485        * ?+=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t ),
    25022486        * ?-=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t );
    2503 forall( otype T ) T _Atomic restrict
     2487forall( type T ) T _Atomic restrict
    25042488        * ?+=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ),
    25052489        * ?-=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ),
    25062490        * ?+=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t ),
    25072491        * ?-=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t );
    2508 forall( otype T ) T _Atomic volatile
     2492forall( type T ) T _Atomic volatile
    25092493        * ?+=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ),
    25102494        * ?-=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ),
    25112495        * ?+=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25122496        * ?-=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t );
    2513 forall( otype T ) T const restrict
     2497forall( type T ) T const restrict
    25142498        * ?+=?( T const restrict * restrict volatile *, ptrdiff_t ),
    25152499        * ?-=?( T const restrict * restrict volatile *, ptrdiff_t ),
    25162500        * ?+=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t ),
    25172501        * ?-=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t );
    2518 forall( otype T ) T const volatile
     2502forall( type T ) T const volatile
    25192503        * ?+=?( T const volatile * restrict volatile *, ptrdiff_t ),
    25202504        * ?-=?( T const volatile * restrict volatile *, ptrdiff_t ),
    25212505        * ?+=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25222506        * ?-=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t );
    2523 forall( otype T ) T restrict volatile
     2507forall( type T ) T restrict volatile
    25242508        * ?+=?( T restrict volatile * restrict volatile *, ptrdiff_t ),
    25252509        * ?-=?( T restrict volatile * restrict volatile *, ptrdiff_t ),
    25262510        * ?+=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25272511        * ?-=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t );
    2528 forall( otype T ) T _Atomic const restrict
     2512forall( type T ) T _Atomic const restrict
    25292513        * ?+=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ),
    25302514        * ?-=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ),
    25312515        * ?+=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t ),
    25322516        * ?-=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t );
    2533 forall( otype T ) T _Atomic const volatile
     2517forall( type T ) T _Atomic const volatile
    25342518        * ?+=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ),
    25352519        * ?-=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ),
    25362520        * ?+=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25372521        * ?-=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t );
    2538 forall( otype T ) T _Atomic restrict volatile
     2522forall( type T ) T _Atomic restrict volatile
    25392523        * ?+=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ),
    25402524        * ?-=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ),
    25412525        * ?+=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25422526        * ?-=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t );
    2543 forall( otype T ) T const restrict volatile
     2527forall( type T ) T const restrict volatile
    25442528        * ?+=?( T const restrict volatile * restrict volatile *, ptrdiff_t ),
    25452529        * ?-=?( T const restrict volatile * restrict volatile *, ptrdiff_t ),
    25462530        * ?+=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25472531        * ?-=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t );
    2548 forall( otype T ) T _Atomic const restrict volatile
     2532forall( type T ) T _Atomic const restrict volatile
    25492533        * ?+=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ),
    25502534        * ?-=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ),
     
    28582842This sort of declaration is illegal because the scope of the type identifiers ends at the end of the declaration, but the scope of the structure tag does not.
    28592843\begin{lstlisting}
    2860 forall( otype T ) struct Pair { T a, b;
     2844forall( type T ) struct Pair { T a, b;
    28612845} mkPair( T, T ); // illegal
    28622846\end{lstlisting}
     
    28832867If this restriction were lifted, it would be possible to write
    28842868\begin{lstlisting}
    2885 forall( otype T ) T * alloc( void );@\use{alloc}@ int *p = alloc();
     2869forall( type T ) T * alloc( void );@\use{alloc}@ int *p = alloc();
    28862870\end{lstlisting}
    28872871Here \lstinline$alloc()$ would receive \lstinline$int$ as an inferred argument, and return an
     
    28922876\lstinline$T$:
    28932877\begin{lstlisting}
    2894 forall( otype T ) T * alloc( T initial_value );@\use{alloc}@
     2878forall( type T ) T * alloc( T initial_value );@\use{alloc}@
    28952879\end{lstlisting}
    28962880\end{rationale}
     
    29152899\begin{lstlisting}
    29162900int fi( int );
    2917 forall( otype T ) T fT( T );
     2901forall( type T ) T fT( T );
    29182902\end{lstlisting}
    29192903\lstinline$fi()$ takes an \lstinline$int$ and returns an \lstinline$int$. \lstinline$fT()$ takes a
     
    29212905\begin{lstlisting}
    29222906int (*pfi )( int ) = fi;
    2923 forall( otype T ) T (*pfT )( T ) = fT;
     2907forall( type T ) T (*pfT )( T ) = fT;
    29242908\end{lstlisting}
    29252909\lstinline$pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$ is not polymorphic, but the function it points at is.
     
    29282912        return pfi;
    29292913}
    2930 forall( otype T ) T (*fvpfT( void ))( T ) {
     2914forall( type T ) T (*fvpfT( void ))( T ) {
    29312915        return pfT;
    29322916}
     
    29342918\lstinline$fvpfi()$ and \lstinline$fvpfT()$ are functions taking no arguments and returning pointers to functions. \lstinline$fvpfT()$ is monomorphic, but the function that its return value points at is polymorphic.
    29352919\begin{lstlisting}
    2936 forall( otype T ) int ( *fTpfi( T ) )( int );
    2937 forall( otype T ) T ( *fTpfT( T ) )( T );
    2938 forall( otype T, otype U ) U ( *fTpfU( T ) )( U );
     2920forall( type T ) int ( *fTpfi( T ) )( int );
     2921forall( type T ) T ( *fTpfT( T ) )( T );
     2922forall( type T, type U ) U ( *fTpfU( T ) )( U );
    29392923\end{lstlisting}
    29402924\lstinline$fTpfi()$ is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer.
     
    29462930\lstinline$char *$.
    29472931\begin{lstlisting}
    2948 forall( otype T, otype U, otype V ) U * f( T *, U, V * const );
    2949 forall( otype U, otype V, otype W ) U * g( V *, U, W * const );
     2932forall( type T, type U, type V ) U * f( T *, U, V * const );
     2933forall( type U, type V, type W ) U * g( V *, U, W * const );
    29502934\end{lstlisting}
    29512935The functions \lstinline$f()$ and \lstinline$g()$ have compatible types.
     
    29552939Replacing every \(f_i\) by \(g_i\) in \(f\) gives
    29562940\begin{lstlisting}
    2957 forall( otype V, otype U, otype W ) U * f( V *, U, W * const );
     2941forall( type V, type U, type W ) U * f( V *, U, W * const );
    29582942\end{lstlisting} which has a return type and parameter list that is compatible with \(g\).
    29592943\begin{rationale}
     
    31433127\examples
    31443128\begin{lstlisting}
    3145 forall( otype T | T ?*?( T, T ))@\use{?*?}@
     3129forall( type T | T ?*?( T, T ))@\use{?*?}@
    31463130T square( T val ) {@\impl{square}@
    31473131        return val + val;
    31483132}
    3149 trait summable( otype T ) {@\impl{summable}@
     3133context summable( type T ) {@\impl{summable}@
    31503134        T ?+=?( T *, T );@\use{?+=?}@
    31513135        const T 0;@\use{0}@
    31523136};
    3153 trait list_of( otype List, otype Element ) {@\impl{list_of}@
     3137context list_of( type List, type Element ) {@\impl{list_of}@
    31543138        Element car( List );
    31553139        List cdr( List );
     
    31583142        int is_nil( List );
    31593143};
    3160 trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {};
     3144context sum_list( type List, type Element | summable( Element ) | list_of( List, Element ) ) {};
    31613145\end{lstlisting}
    31623146\lstinline$sum_list$ contains seven declarations, which describe a list whose elements can be added up.
     
    32203204Incomplete type declarations allow compact mutually-recursive types.
    32213205\begin{lstlisting}
    3222 otype t1; // incomplete type declaration
    3223 otype t2 = struct { t1 * p; ... };
    3224 otype t1 = struct { t2 * p; ... };
     3206type t1; // incomplete type declaration
     3207type t2 = struct { t1 * p; ... };
     3208type t1 = struct { t2 * p; ... };
    32253209\end{lstlisting}
    32263210Without them, mutual recursion could be handled by declaring mutually recursive structures, then initializing the types to those structures.
    32273211\begin{lstlisting}
    32283212struct s1;
    3229 otype t2 = struct s2 { struct s1 * p; ... };
    3230 otype t1 = struct s1 { struct s2 * p; ... };
     3213type t2 = struct s2 { struct s1 * p; ... };
     3214type t1 = struct s1 { struct s2 * p; ... };
    32313215\end{lstlisting}
    32323216This introduces extra names, and may force the programmer to cast between the types and their implementations.
     
    32833267This prevents the declaration of types that contain each other.
    32843268\begin{lstlisting}
    3285 otype t1;
    3286 otype t2 = t1; // illegal: incomplete type t1
    3287 otype t1 = t2;
     3269type t1;
     3270type t2 = t1; // illegal: incomplete type t1
     3271type t1 = t2;
    32883272\end{lstlisting}
    32893273
     
    32923276 types}.
    32933277\begin{lstlisting}
    3294 extern otype Huge; // extended-precision integer type
    3295 otype Rational = struct {
     3278extern type Huge; // extended-precision integer type
     3279type Rational = struct {
    32963280        Huge numerator, denominator;    // illegal
    32973281};
     
    33323316\begin{lstlisting}
    33333317#include <stdlib.h>
    3334 T * new( otype T ) { return ( T * )malloc( sizeof( T) ); };
     3318T * new( type T ) { return ( T * )malloc( sizeof( T) ); };
    33353319@\ldots@ int * ip = new( int );
    33363320\end{lstlisting}
     
    33433327Since type declarations create new types, instances of types are always passed by value.
    33443328\begin{lstlisting}
    3345 otype A1 = int[2];
     3329type A1 = int[2];
    33463330void f1( A1 a ) { a[0] = 0; };
    3347 otypedef int A2[2];
     3331typedef int A2[2];
    33483332void f2( A2 a ) { a[0] = 0; };
    33493333A1 v1;
     
    33623346That unit might contain the declarations
    33633347\begin{lstlisting}
    3364 otype Complex = struct { float re, im; };@\impl{Complex}@
     3348type Complex = struct { float re, im; };@\impl{Complex}@
    33653349Complex cplx_i = { 0.0, 1.0 };@\impl{cplx_i}@
    33663350float abs( Complex c ) {@\impl{abs( Complex )}@
     
    33713355
    33723356\begin{lstlisting}
    3373 otype Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.
     3357type Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.
    33743358Time_of_day ?+?( Time_of_day t1, int seconds ) {@\impl{?+?}@
    33753359        return (( int)t1 + seconds ) % 86400;
     
    34453429\examples
    34463430\begin{lstlisting}
    3447 trait s( otype T ) {
     3431context s( type T ) {
    34483432        T a, b;
    34493433} struct impl { int left, right; } a = { 0, 0 };
    3450 otype Pair | s( Pair ) = struct impl;
     3434type Pair | s( Pair ) = struct impl;
    34513435Pair b = { 1, 1 };
    34523436\end{lstlisting}
     
    34563440\lstinline$Pair b$ is compulsory because there is no \lstinline$struct impl b$ to construct a value from.
    34573441\begin{lstlisting}
    3458 trait ss( otype T ) {
     3442context ss( type T ) {
    34593443        T clone( T );
    34603444        void munge( T * );
    34613445}
    3462 otype Whatsit | ss( Whatsit );@\use{Whatsit}@
    3463 otype Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@
     3446type Whatsit | ss( Whatsit );@\use{Whatsit}@
     3447type Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@
    34643448        Whatsit; // anonymous member
    34653449        int extra;
     
    34823466Default functions and objects are subject to the normal scope rules.
    34833467\begin{lstlisting}
    3484 otype T = @\ldots@;
     3468type T = @\ldots@;
    34853469T a_T = @\ldots@;               // Default assignment used.
    34863470T ?=?( T *, T );
     
    37513735The assertion ``\lstinline$scalar( Complex )$'' should be read as ``type \lstinline$Complex$ is scalar''.
    37523736\begin{lstlisting}
    3753 trait scalar( otype T ) {@\impl{scalar}@
     3737context scalar( type T ) {@\impl{scalar}@
    37543738        int !?( T );
    37553739        int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T );
     
    37613745This is equivalent to inheritance of specifications.
    37623746\begin{lstlisting}
    3763 trait arithmetic( otype T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@
     3747context arithmetic( type T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@
    37643748        T +?( T ), -?( T );
    37653749        T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T );
     
    37703754\define{integral types}.
    37713755\begin{lstlisting}
    3772 trait integral( otype T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@
     3756context integral( type T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@
    37733757        T ~?( T );
    37743758        T ?&?( T, T ), ?|?( T, T ), ?^?( T, T );
     
    37843768The only operation that can be applied to all modifiable lvalues is simple assignment.
    37853769\begin{lstlisting}
    3786 trait m_lvalue( otype T ) {@\impl{m_lvalue}@
     3770context m_lvalue( type T ) {@\impl{m_lvalue}@
    37873771        T ?=?( T *, T );
    37883772};
     
    37943778Scalars can also be incremented and decremented.
    37953779\begin{lstlisting}
    3796 trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@
     3780context m_l_scalar( type T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@
    37973781        T ?++( T * ), ?--( T * );@\use{scalar}@@\use{m_lvalue}@
    37983782        T ++?( T * ), --?( T * );
     
    38033787Note that this results in the ``inheritance'' of \lstinline$scalar$ along both paths.
    38043788\begin{lstlisting}
    3805 trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@
     3789context m_l_arithmetic( type T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@
    38063790        T ?/=?( T *, T ), ?*=?( T *, T );@\use{m_l_scalar}@@\use{arithmetic}@
    38073791        T ?+=?( T *, T ), ?-=?( T *, T );
    38083792};
    3809 trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@
     3793context m_l_integral( type T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@
    38103794        T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );@\use{m_l_arithmetic}@
    38113795        T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );@\use{integral}@
     
    38273811\lstinline$arithmetic$, so these operators cannot be consolidated in \lstinline$scalar$.
    38283812\begin{lstlisting}
    3829 trait pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@
     3813context pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@
    38303814        P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int );
    38313815        ptrdiff_t ?-?( P, P );
    38323816};
    3833 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@
     3817context m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@
    38343818        P ?+=?( P *, long int ), ?-=?( P *, long int );
    38353819        P ?=?( P *, void * );
     
    38433827``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''.
    38443828\begin{lstlisting}
    3845 trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@
     3829context ptr_to( type P | pointer( P ), type T ) {@\impl{ptr_to}@@\use{pointer}@
    38463830        lvalue T *?( P );
    38473831        lvalue T ?[?]( P, long int );
    38483832};
    3849 trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
     3833context ptr_to_const( type P | pointer( P ), type T ) {@\impl{ptr_to_const}@
    38503834        const lvalue T *?( P );
    38513835        const lvalue T ?[?]( P, long int );@\use{pointer}@
    38523836};
    3853 trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
     3837context ptr_to_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_volatile}@
    38543838        volatile lvalue T *?( P );
    38553839        volatile lvalue T ?[?]( P, long int );@\use{pointer}@
    38563840};
    3857 trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@
     3841context ptr_to_const_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_const_volatile}@
    38583842        const volatile lvalue T *?( P );@\use{pointer}@
    38593843        const volatile lvalue T ?[?]( P, long int );
     
    38653849``\lstinline$ptr_to$'' specifications.
    38663850\begin{lstlisting}
    3867 trait m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {
     3851context m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ type T | ptr_to( P, T )@\use{ptr_to}@ {
    38683852        P ?=?( P *, T * );
    38693853        T * ?=?( T **, P );
    38703854};
    3871 trait m_l_ptr_to_const( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) {
     3855context m_l_ptr_to_const( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ type T | ptr_to_const( P, T )@\use{ptr_to_const}@) {
    38723856        P ?=?( P *, const T * );
    38733857        const T * ?=?( const T **, P );
    38743858};
    3875 trait m_l_ptr_to_volatile( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@
     3859context m_l_ptr_to_volatile( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ type T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@
    38763860        P ?=?( P *, volatile T * );
    38773861        volatile T * ?=?( volatile T **, P );
    38783862};
    3879 trait m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@
     3863context m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@
    38803864                type T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {@\use{m_l_ptr_to_const}@@\use{m_l_ptr_to_volatile}@
    38813865        P ?=?( P *, const volatile T * );
     
    38873871An alternative specification can make use of the fact that qualification of the pointed-at type is part of a pointer type to capture that regularity.
    38883872\begin{lstlisting}
    3889 trait m_l_ptr_like( type MyP | m_l_pointer( MyP ),@\use{m_l_pointer}@@\impl{m_l_ptr_like}@ type CP | m_l_pointer( CP ) ) {
     3873context m_l_ptr_like( type MyP | m_l_pointer( MyP ),@\use{m_l_pointer}@@\impl{m_l_ptr_like}@ type CP | m_l_pointer( CP ) ) {
    38903874        MyP ?=?( MyP *, CP );
    38913875        CP ?=?( CP *, MyP );
     
    39203904C and \CFA have an extra, non-obvious comparison operator: ``\lstinline$!$'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise.
    39213905\begin{lstlisting}
    3922 trait comparable( otype T ) {
     3906context comparable( type T ) {
    39233907        const T 0;
    39243908        int compare( T, T );
    39253909}
    3926 forall( otype T | comparable( T ) ) int ?<?( T l, T r ) {
     3910forall( type T | comparable( T ) ) int ?<?( T l, T r ) {
    39273911        return compare( l, r ) < 0;
    39283912}
    39293913// ... similarly for <=, ==, >=, >, and !=.
    3930 forall( otype T | comparable( T ) ) int !?( T operand ) {
     3914forall( type T | comparable( T ) ) int !?( T operand ) {
    39313915        return !compare( operand, 0 );
    39323916}
     
    39403924Similarly, a complete integral type would provide integral operations based on integral assignment operations.
    39413925\begin{lstlisting}
    3942 trait arith_base( otype T ) {
     3926context arith_base( type T ) {
    39433927        const T 1;
    39443928        T ?+=?( T *, T ), ?-=?( T *, T ), ?*=?( T *, T ), ?/=?( T *, T );
    39453929}
    3946 forall( otype T | arith_base( T ) ) T ?+?( T l, T r ) {
     3930forall( type T | arith_base( T ) ) T ?+?( T l, T r ) {
    39473931        return l += r;
    39483932}
    3949 forall( otype T | arith_base( T ) ) T ?++( T * operand ) {
     3933forall( type T | arith_base( T ) ) T ?++( T * operand ) {
    39503934        T temporary = *operand;
    39513935        *operand += 1;
    39523936        return temporary;
    39533937}
    3954 forall( otype T | arith_base( T ) ) T ++?( T * operand ) {
     3938forall( type T | arith_base( T ) ) T ++?( T * operand ) {
    39553939        return *operand += 1;
    39563940}
    39573941// ... similarly for -, --, *, and /.
    3958 trait int_base( otype T ) {
     3942context int_base( type T ) {
    39593943        T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );
    39603944        T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );
    39613945}
    3962 forall( otype T | int_base( T ) ) T ?&?( T l, T r ) {
     3946forall( type T | int_base( T ) ) T ?&?( T l, T r ) {
    39633947        return l &= r;
    39643948}
Note: See TracChangeset for help on using the changeset viewer.