Changeset b3f9a0cb for doc/refrat


Ignore:
Timestamp:
Apr 4, 2016, 1:18:17 PM (10 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
afc1045
Parents:
89173242 (diff), 3cfe27f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/refrat/refrat.tex

    r89173242 rb3f9a0cb  
    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 \urlstyle{sf}
     19\renewcommand{\UrlFont}{\small\sf}
    2020
    2121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    2323% Names used in the document.
    2424
    25 \newcommand{\CFA}{Cforall\xspace}               % set language text name
    26 \newcommand{\CFAA}{C$\forall$\xspace}   % set language symbolic name
     25\newcommand{\CFA}{C$\forall$\xspace}    % set language symbolic name
     26\newcommand{\CFL}{Cforall\xspace}               % set language text 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
    3552\renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}}
    3653\renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}}
     
    5976\renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}}
    6077\renewcommand\subsection{\@startsection{subsection}{2}{\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}}
     78\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
    6279\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}}
    6380
     81% index macros
    6482\newcommand{\italic}[1]{\emph{\hyperpage{#1}}}
    6583\newcommand{\definition}[1]{\textbf{\hyperpage{#1}}}
     
    97115
    98116% blocks and titles
    99 \newcommand{\define}[1]{\emph{#1\/}\index{#1}}
    100117\newenvironment{rationale}{%
    101118  \begin{quotation}\noindent$\Box$\enspace
     
    103120  \hfill\enspace$\Box$\end{quotation}
    104121}%
     122\newcommand{\define}[1]{\emph{#1\/}\index{#1}}
    105123\newcommand{\rewrite}{\(\Rightarrow\)}
    106124\newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent}
     
    131149\newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}}
    132150
    133 % adjust listings macros
     151% CFA based on ANSI C
    134152\lstdefinelanguage{CFA}[ANSI]{C}%
    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,},
     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,},
    138156}%
    139157
     
    141159language=CFA,
    142160columns=flexible,
    143 basicstyle=\sf\small,
     161basicstyle=\sf\relsize{-1},
    144162tabsize=4,
    145163xleftmargin=\parindent,
    146164escapechar=@,
    147165keepspaces=true,
    148 %showtabs=true,
    149 %tab=\rightarrowfill,
     166showstringspaces=false,
     167showlines=true,
    150168}%
    151169
     
    174192
    175193\title{\Huge
    176 \CFA (\CFAA) Reference Manual and Rationale
     194\CFA (\CFL) Reference Manual and Rationale
    177195}% title
    178196\author{\huge
     
    280298An instantiation of the generic type is written by specifying the type parameters in parentheses after the name of the generic type generator:
    281299\begin{lstlisting}
    282 forall( type T | sumable( T ) ) struct pair {
     300forall( otype T | sumable( T ) ) struct pair {
    283301        T x;
    284302        T y;
     
    292310Polymorphic 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:
    293311\begin{lstlisting}
    294 forall( type T ) void swap( pair(T) *p ) {
     312forall( otype T ) void swap( pair(T) *p ) {
    295313        T z = p->x;
    296314        p->x = p->y;
     
    302320\subsubsection{Constraints}
    303321
    304 To 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.
     322To avoid unduly constraining implementors, the generic type generator definition must be visible at any point where it is instantiated.
     323Forward 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.
    305324
    306325\examples
    307326\begin{lstlisting}
    308 forall( type T ) struct A;
    309 
    310 forall( type T ) struct B {
     327forall( otype T ) struct A;
     328
     329forall( otype T ) struct B {
    311330        A(T) *a;                        // legal, but cannot instantiate B(T)
    312331};
     
    314333B(T) x;                                 // illegal, *x.a is of an incomplete generic type
    315334 
    316 forall( type T ) struct A {
     335forall( otype T ) struct A {
    317336        B( T ) *b;
    318337};
     
    321340
    322341// box.h:
    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 );
     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 );
    326345       
    327346// main.c:
     
    410429
    411430\subsubsection{Specialization}
    412 A 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}.
     431A 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}.
    414432Any value that is legal for the inferred parameter may be used, including other inferred parameters.
    415433
    416 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
    417   type} with or can be specialized to the type of the assertion parameter.  The assertion parameter is bound to that object or function.
     434If, 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.
     435The assertion parameter is bound to that object or function.
    418436
    419437The 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.
     
    422440The type
    423441\begin{lstlisting}
    424 forall( type T, type U ) void (*)( T, U );
     442forall( otype T, otype U ) void (*)( T, U );
    425443\end{lstlisting}
    426444can be specialized to (among other things)
    427445\begin{lstlisting}
    428 forall( type T ) void (*)( T, T );              // U bound to T
    429 forall( type T ) void (*)( T, real );   // U bound to real
    430 forall( type U ) void (*)( real, U );   // T bound to real
     446forall( otype T ) void (*)( T, T );             // U bound to T
     447forall( otype T ) void (*)( T, real );  // U bound to real
     448forall( otype U ) void (*)( real, U );  // T bound to real
    431449void f( real, real );                                   // both bound to real
    432450\end{lstlisting}
     
    434452The type
    435453\begin{lstlisting}
    436 forall( type T | T ?+?( T, T ) ) T (*)( T );
     454forall( otype T | T ?+?( T, T ) ) T (*)( T );
    437455\end{lstlisting}
    438456can be specialized to (among other things)
     
    494512If \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:
    495513\lstinline$unsigned short$ to \lstinline$int$ to \lstinline$unsigned$.
    496 Otherwise,
    497 \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1.
     514Otherwise, \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1.
    498515
    499516\item
     
    508525        \rhs \lstinline$forall$
    509526        \rhs \lstinline$lvalue$
    510         \rhs \lstinline$context$
     527        \rhs \lstinline$trait$
    511528        \rhs \lstinline$dtype$
    512529        \rhs \lstinline$ftype$
     
    539556A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type.
    540557
    541 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
    542 0 as a special case.
     558In 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.
    543559However, 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.
    544560Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline$_Bool$.
     
    836852\predefined
    837853\begin{lstlisting}
    838 forall( type T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@
    839 forall( type T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );
    840 forall( type T ) lvalue const T ?[?]( const T *, ptrdiff_t );
    841 forall( type T ) lvalue restrict T ?[?]( restrict T *, ptrdiff_t );
    842 forall( type T ) lvalue volatile T ?[?]( volatile T *, ptrdiff_t );
    843 forall( type T ) lvalue _Atomic const T ?[?]( _Atomic const T *, ptrdiff_t );
    844 forall( type T ) lvalue _Atomic restrict T ?[?]( _Atomic restrict T *, ptrdiff_t );
    845 forall( type T ) lvalue _Atomic volatile T ?[?]( _Atomic volatile T *, ptrdiff_t );
    846 forall( type T ) lvalue const restrict T ?[?]( const restrict T *, ptrdiff_t );
    847 forall( type T ) lvalue const volatile T ?[?]( const volatile T *, ptrdiff_t );
    848 forall( type T ) lvalue restrict volatile T ?[?]( restrict volatile T *, ptrdiff_t );
    849 forall( type T ) lvalue _Atomic const restrict T ?[?]( _Atomic const restrict T *, ptrdiff_t );
    850 forall( type T ) lvalue _Atomic const volatile T ?[?]( _Atomic const volatile T *, ptrdiff_t );
    851 forall( type T ) lvalue _Atomic restrict volatile T ?[?]( _Atomic restrict volatile T *, ptrdiff_t );
    852 forall( type T ) lvalue const restrict volatile T ?[?]( const restrict volatile T *, ptrdiff_t );
    853 forall( type T ) lvalue _Atomic const restrict volatile T ?[?]( _Atomic const restrict volatile T *, ptrdiff_t );
     854forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@
     855forall( otype T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );
     856forall( otype T ) lvalue const T ?[?]( const T *, ptrdiff_t );
     857forall( otype T ) lvalue restrict T ?[?]( restrict T *, ptrdiff_t );
     858forall( otype T ) lvalue volatile T ?[?]( volatile T *, ptrdiff_t );
     859forall( otype T ) lvalue _Atomic const T ?[?]( _Atomic const T *, ptrdiff_t );
     860forall( otype T ) lvalue _Atomic restrict T ?[?]( _Atomic restrict T *, ptrdiff_t );
     861forall( otype T ) lvalue _Atomic volatile T ?[?]( _Atomic volatile T *, ptrdiff_t );
     862forall( otype T ) lvalue const restrict T ?[?]( const restrict T *, ptrdiff_t );
     863forall( otype T ) lvalue const volatile T ?[?]( const volatile T *, ptrdiff_t );
     864forall( otype T ) lvalue restrict volatile T ?[?]( restrict volatile T *, ptrdiff_t );
     865forall( otype T ) lvalue _Atomic const restrict T ?[?]( _Atomic const restrict T *, ptrdiff_t );
     866forall( otype T ) lvalue _Atomic const volatile T ?[?]( _Atomic const volatile T *, ptrdiff_t );
     867forall( otype T ) lvalue _Atomic restrict volatile T ?[?]( _Atomic restrict volatile T *, ptrdiff_t );
     868forall( otype T ) lvalue const restrict volatile T ?[?]( const restrict volatile T *, ptrdiff_t );
     869forall( otype T ) lvalue _Atomic const restrict volatile T ?[?]( _Atomic const restrict volatile T *, ptrdiff_t );
    854870\end{lstlisting}
    855871\semantics
     
    914930\begin{rationale}
    915931One 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}.
    916 For 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$.
     932For 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$.
    917933
    918934\CFA\index{deficiencies!generalizability} does not fully possess this property, because
     
    928944f = g( d, f );          // (3) (unsafe conversion to float)
    929945\end{lstlisting}
    930 If \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
     946If \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
    931947\lstinline$double$, and the result would be a \lstinline$double$.
    932948
    933949Another example is the function ``\lstinline$void h( int *);$''.
    934950This function can be passed a
    935 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( type T ) void h( T *);$'' can not.
     951\lstinline$void *$ argument, but the generalization ``\lstinline$forall( otype T ) void h( T *);$'' can not.
    936952In this case, \lstinline$void$ is not a valid value for \lstinline$T$ because it is not an object type.
    937953If unsafe conversions were allowed, \lstinline$T$ could be inferred to be \emph{any} object type, which is undesirable.
     
    941957A function called ``\lstinline$?()$'' might be part of a numerical differentiation package.
    942958\begin{lstlisting}
    943 extern type Derivative;
     959extern otype Derivative;
    944960extern double ?()( Derivative, double );
    945961extern Derivative derivative_of( double (*f)( double ) );
     
    962978
    963979\begin{lstlisting}
    964 forall( type T ) T h( T );
     980forall( otype T ) T h( T );
    965981double d = h( 1.5 );
    966982\end{lstlisting}
     
    969985
    970986\begin{lstlisting}
    971 forall( type T, type U ) void g( T, U );        // (4)
    972 forall( type T ) void g( T, T );                        // (5)
    973 forall( type T ) void g( T, long );                     // (6)
     987forall( otype T, otype U ) void g( T, U );      // (4)
     988forall( otype T ) void g( T, T );                       // (5)
     989forall( otype T ) void g( T, long );                    // (6)
    974990void g( long, long );                                           // (7)
    975991double d;
     
    9911007The fourth call has no interpretation for (5), because its arguments must have compatible type. (4) is chosen because it does not involve unsafe conversions.
    9921008\begin{lstlisting}
    993 forall( type T ) T min( T, T );
     1009forall( otype T ) T min( T, T );
    9941010double max( double, double );
    995 context min_max( T ) {@\impl{min_max}@
     1011trait min_max( T ) {@\impl{min_max}@
    9961012        T min( T, T );
    9971013        T max( T, T );
    9981014}
    999 forall( type U | min_max( U ) ) void shuffle( U, U );
     1015forall( otype U | min_max( U ) ) void shuffle( U, U );
    10001016shuffle( 9, 10 );
    10011017\end{lstlisting}
     
    10471063long double ?++( volatile long double * ), ?++( _Atomic volatile long double * );
    10481064
    1049 forall( type T ) T * ?++( T * restrict volatile * ), * ?++( T * _Atomic restrict volatile * );
    1050 forall( type T ) _Atomic T * ?++( _Atomic T * restrict volatile * ), * ?++( _Atomic T * _Atomic restrict volatile * );
    1051 forall( type T ) const T * ?++( const T * restrict volatile * ), * ?++( const T * _Atomic restrict volatile * );
    1052 forall( type T ) volatile T * ?++( volatile T * restrict volatile * ), * ?++( volatile T * _Atomic restrict volatile * );
    1053 forall( type T ) restrict T * ?++( restrict T * restrict volatile * ), * ?++( restrict T * _Atomic restrict volatile * );
    1054 forall( type T ) _Atomic const T * ?++( _Atomic const T * restrict volatile * ),
     1065forall( otype T ) T * ?++( T * restrict volatile * ), * ?++( T * _Atomic restrict volatile * );
     1066forall( otype T ) _Atomic T * ?++( _Atomic T * restrict volatile * ), * ?++( _Atomic T * _Atomic restrict volatile * );
     1067forall( otype T ) const T * ?++( const T * restrict volatile * ), * ?++( const T * _Atomic restrict volatile * );
     1068forall( otype T ) volatile T * ?++( volatile T * restrict volatile * ), * ?++( volatile T * _Atomic restrict volatile * );
     1069forall( otype T ) restrict T * ?++( restrict T * restrict volatile * ), * ?++( restrict T * _Atomic restrict volatile * );
     1070forall( otype T ) _Atomic const T * ?++( _Atomic const T * restrict volatile * ),
    10551071        * ?++( _Atomic const T * _Atomic restrict volatile * );
    1056 forall( type T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ),
     1072forall( otype T ) _Atomic restrict T * ?++( _Atomic restrict T * restrict volatile * ),
    10571073        * ?++( _Atomic restrict T * _Atomic restrict volatile * );
    1058 forall( type T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ),
     1074forall( otype T ) _Atomic volatile T * ?++( _Atomic volatile T * restrict volatile * ),
    10591075        * ?++( _Atomic volatile T * _Atomic restrict volatile * );
    1060 forall( type T ) const restrict T * ?++( const restrict T * restrict volatile * ),
     1076forall( otype T ) const restrict T * ?++( const restrict T * restrict volatile * ),
    10611077        * ?++( const restrict T * _Atomic restrict volatile * );
    1062 forall( type T ) const volatile T * ?++( const volatile T * restrict volatile * ),
     1078forall( otype T ) const volatile T * ?++( const volatile T * restrict volatile * ),
    10631079        * ?++( const volatile T * _Atomic restrict volatile * );
    1064 forall( type T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ),
     1080forall( otype T ) restrict volatile T * ?++( restrict volatile T * restrict volatile * ),
    10651081        * ?++( restrict volatile T * _Atomic restrict volatile * );
    1066 forall( type T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ),
     1082forall( otype T ) _Atomic const restrict T * ?++( _Atomic const restrict T * restrict volatile * ),
    10671083        * ?++( _Atomic const restrict T * _Atomic restrict volatile * );
    1068 forall( type T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ),
     1084forall( otype T ) _Atomic const volatile T * ?++( _Atomic const volatile T * restrict volatile * ),
    10691085        * ?++( _Atomic const volatile T * _Atomic restrict volatile * );
    1070 forall( type T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ),
     1086forall( otype T ) _Atomic restrict volatile T * ?++( _Atomic restrict volatile T * restrict volatile * ),
    10711087        * ?++( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1072 forall( type T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ),
     1088forall( otype T ) const restrict volatile T * ?++( const restrict volatile T * restrict volatile * ),
    10731089        * ?++( const restrict volatile T * _Atomic restrict volatile * );
    1074 forall( type T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ),
     1090forall( otype T ) _Atomic const restrict volatile T * ?++( _Atomic const restrict volatile T * restrict volatile * ),
    10751091        * ?++( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    10761092
     
    10911107long double ?--( volatile long double * ), ?--( _Atomic volatile long double * );
    10921108
    1093 forall( type T ) T * ?--( T * restrict volatile * ), * ?--( T * _Atomic restrict volatile * );
    1094 forall( type T ) _Atomic T * ?--( _Atomic T * restrict volatile * ), * ?--( _Atomic T * _Atomic restrict volatile * );
    1095 forall( type T ) const T * ?--( const T * restrict volatile * ), * ?--( const T * _Atomic restrict volatile * );
    1096 forall( type T ) volatile T * ?--( volatile T * restrict volatile * ), * ?--( volatile T * _Atomic restrict volatile * );
    1097 forall( type T ) restrict T * ?--( restrict T * restrict volatile * ), * ?--( restrict T * _Atomic restrict volatile * );
    1098 forall( type T ) _Atomic const T * ?--( _Atomic const T * restrict volatile * ),
     1109forall( otype T ) T * ?--( T * restrict volatile * ), * ?--( T * _Atomic restrict volatile * );
     1110forall( otype T ) _Atomic T * ?--( _Atomic T * restrict volatile * ), * ?--( _Atomic T * _Atomic restrict volatile * );
     1111forall( otype T ) const T * ?--( const T * restrict volatile * ), * ?--( const T * _Atomic restrict volatile * );
     1112forall( otype T ) volatile T * ?--( volatile T * restrict volatile * ), * ?--( volatile T * _Atomic restrict volatile * );
     1113forall( otype T ) restrict T * ?--( restrict T * restrict volatile * ), * ?--( restrict T * _Atomic restrict volatile * );
     1114forall( otype T ) _Atomic const T * ?--( _Atomic const T * restrict volatile * ),
    10991115        * ?--( _Atomic const T * _Atomic restrict volatile * );
    1100 forall( type T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ),
     1116forall( otype T ) _Atomic restrict T * ?--( _Atomic restrict T * restrict volatile * ),
    11011117        * ?--( _Atomic restrict T * _Atomic restrict volatile * );
    1102 forall( type T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ),
     1118forall( otype T ) _Atomic volatile T * ?--( _Atomic volatile T * restrict volatile * ),
    11031119        * ?--( _Atomic volatile T * _Atomic restrict volatile * );
    1104 forall( type T ) const restrict T * ?--( const restrict T * restrict volatile * ),
     1120forall( otype T ) const restrict T * ?--( const restrict T * restrict volatile * ),
    11051121        * ?--( const restrict T * _Atomic restrict volatile * );
    1106 forall( type T ) const volatile T * ?--( const volatile T * restrict volatile * ),
     1122forall( otype T ) const volatile T * ?--( const volatile T * restrict volatile * ),
    11071123        * ?--( const volatile T * _Atomic restrict volatile * );
    1108 forall( type T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ),
     1124forall( otype T ) restrict volatile T * ?--( restrict volatile T * restrict volatile * ),
    11091125        * ?--( restrict volatile T * _Atomic restrict volatile * );
    1110 forall( type T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ),
     1126forall( otype T ) _Atomic const restrict T * ?--( _Atomic const restrict T * restrict volatile * ),
    11111127        * ?--( _Atomic const restrict T * _Atomic restrict volatile * );
    1112 forall( type T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ),
     1128forall( otype T ) _Atomic const volatile T * ?--( _Atomic const volatile T * restrict volatile * ),
    11131129        * ?--( _Atomic const volatile T * _Atomic restrict volatile * );
    1114 forall( type T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ),
     1130forall( otype T ) _Atomic restrict volatile T * ?--( _Atomic restrict volatile T * restrict volatile * ),
    11151131        * ?--( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1116 forall( type T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ),
     1132forall( otype T ) const restrict volatile T * ?--( const restrict volatile T * restrict volatile * ),
    11171133        * ?--( const restrict volatile T * _Atomic restrict volatile * );
    1118 forall( type T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ),
     1134forall( otype T ) _Atomic const restrict volatile T * ?--( _Atomic const restrict volatile T * restrict volatile * ),
    11191135        * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    11201136\end{lstlisting}
     
    11951211The expression would be valid if \lstinline$?++$ were declared by
    11961212\begin{lstlisting}
    1197 forall( type T ) T * ?++( T * * );
     1213forall( otype T ) T * ?++( T * * );
    11981214\end{lstlisting} with \lstinline$T$ inferred to be \lstinline$char$.
    11991215
     
    12031219Hence the actual predefined function is
    12041220\begin{lstlisting}
    1205 forall( type T ) T * ?++( T * restrict volatile * );
     1221forall( otype T ) T * ?++( T * restrict volatile * );
    12061222\end{lstlisting} which also accepts a \lstinline$char * *$ argument, because of the safe conversions that add
    12071223\lstinline$volatile$ and \lstinline$restrict$ qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.)
     
    12171233\lstinline$char const volatile *$, so a new overloading is needed:
    12181234\begin{lstlisting}
    1219 forall( type T ) T const volatile * ?++( T const volatile *restrict volatile * );
     1235forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * );
    12201236\end{lstlisting}
    12211237One overloading is needed for each combination of qualifiers in the pointed-at type\index{deficiencies!pointers to qualified types}.
     
    12251241The \lstinline$restrict$ qualifier is handled just like \lstinline$const$ and \lstinline$volatile$ in the previous case:
    12261242\begin{lstlisting}
    1227 forall( type T ) T restrict * ?++( T restrict *restrict volatile * );
     1243forall( otype T ) T restrict * ?++( T restrict *restrict volatile * );
    12281244\end{lstlisting} with \lstinline$T$ inferred to be \lstinline$float *$.
    12291245This 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.
     
    12831299long double ++?( volatile long double * ), ++?( _Atomic volatile long double * );
    12841300
    1285 forall( type T ) T * ++?( T * restrict volatile * ), * ++?( T * _Atomic restrict volatile * );
    1286 forall( type T ) _Atomic T * ++?( _Atomic T * restrict volatile * ), * ++?( _Atomic T * _Atomic restrict volatile * );
    1287 forall( type T ) const T * ++?( const T * restrict volatile * ), * ++?( const T * _Atomic restrict volatile * );
    1288 forall( type T ) volatile T * ++?( volatile T * restrict volatile * ), * ++?( volatile T * _Atomic restrict volatile * );
    1289 forall( type T ) restrict T * ++?( restrict T * restrict volatile * ), * ++?( restrict T * _Atomic restrict volatile * );
    1290 forall( type T ) _Atomic const T * ++?( _Atomic const T * restrict volatile * ),
     1301forall( otype T ) T * ++?( T * restrict volatile * ), * ++?( T * _Atomic restrict volatile * );
     1302forall( otype T ) _Atomic T * ++?( _Atomic T * restrict volatile * ), * ++?( _Atomic T * _Atomic restrict volatile * );
     1303forall( otype T ) const T * ++?( const T * restrict volatile * ), * ++?( const T * _Atomic restrict volatile * );
     1304forall( otype T ) volatile T * ++?( volatile T * restrict volatile * ), * ++?( volatile T * _Atomic restrict volatile * );
     1305forall( otype T ) restrict T * ++?( restrict T * restrict volatile * ), * ++?( restrict T * _Atomic restrict volatile * );
     1306forall( otype T ) _Atomic const T * ++?( _Atomic const T * restrict volatile * ),
    12911307        * ++?( _Atomic const T * _Atomic restrict volatile * );
    1292 forall( type T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ),
     1308forall( otype T ) _Atomic volatile T * ++?( _Atomic volatile T * restrict volatile * ),
    12931309        * ++?( _Atomic volatile T * _Atomic restrict volatile * );
    1294 forall( type T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ),
     1310forall( otype T ) _Atomic restrict T * ++?( _Atomic restrict T * restrict volatile * ),
    12951311        * ++?( _Atomic restrict T * _Atomic restrict volatile * );
    1296 forall( type T ) const volatile T * ++?( const volatile T * restrict volatile * ),
     1312forall( otype T ) const volatile T * ++?( const volatile T * restrict volatile * ),
    12971313        * ++?( const volatile T * _Atomic restrict volatile * );
    1298 forall( type T ) const restrict T * ++?( const restrict T * restrict volatile * ),
     1314forall( otype T ) const restrict T * ++?( const restrict T * restrict volatile * ),
    12991315        * ++?( const restrict T * _Atomic restrict volatile * );
    1300 forall( type T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ),
     1316forall( otype T ) restrict volatile T * ++?( restrict volatile T * restrict volatile * ),
    13011317        * ++?( restrict volatile T * _Atomic restrict volatile * );
    1302 forall( type T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ),
     1318forall( otype T ) _Atomic const volatile T * ++?( _Atomic const volatile T * restrict volatile * ),
    13031319        * ++?( _Atomic const volatile T * _Atomic restrict volatile * );
    1304 forall( type T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ),
     1320forall( otype T ) _Atomic const restrict T * ++?( _Atomic const restrict T * restrict volatile * ),
    13051321        * ++?( _Atomic const restrict T * _Atomic restrict volatile * );
    1306 forall( type T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ),
     1322forall( otype T ) _Atomic restrict volatile T * ++?( _Atomic restrict volatile T * restrict volatile * ),
    13071323        * ++?( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1308 forall( type T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ),
     1324forall( otype T ) const restrict volatile T * ++?( const restrict volatile T * restrict volatile * ),
    13091325        * ++?( const restrict volatile T * _Atomic restrict volatile * );
    1310 forall( type T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ),
     1326forall( otype T ) _Atomic const restrict volatile T * ++?( _Atomic const restrict volatile T * restrict volatile * ),
    13111327        * ++?( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    13121328
     
    13271343long double --?( volatile long double * ), --?( _Atomic volatile long double * );
    13281344
    1329 forall( type T ) T * --?( T * restrict volatile * ), * --?( T * _Atomic restrict volatile * );
    1330 forall( type T ) _Atomic T * --?( _Atomic T * restrict volatile * ), * --?( _Atomic T * _Atomic restrict volatile * );
    1331 forall( type T ) const T * --?( const T * restrict volatile * ), * --?( const T * _Atomic restrict volatile * );
    1332 forall( type T ) volatile T * --?( volatile T * restrict volatile * ), * --?( volatile T * _Atomic restrict volatile * );
    1333 forall( type T ) restrict T * --?( restrict T * restrict volatile * ), * --?( restrict T * _Atomic restrict volatile * );
    1334 forall( type T ) _Atomic const T * --?( _Atomic const T * restrict volatile * ),
     1345forall( otype T ) T * --?( T * restrict volatile * ), * --?( T * _Atomic restrict volatile * );
     1346forall( otype T ) _Atomic T * --?( _Atomic T * restrict volatile * ), * --?( _Atomic T * _Atomic restrict volatile * );
     1347forall( otype T ) const T * --?( const T * restrict volatile * ), * --?( const T * _Atomic restrict volatile * );
     1348forall( otype T ) volatile T * --?( volatile T * restrict volatile * ), * --?( volatile T * _Atomic restrict volatile * );
     1349forall( otype T ) restrict T * --?( restrict T * restrict volatile * ), * --?( restrict T * _Atomic restrict volatile * );
     1350forall( otype T ) _Atomic const T * --?( _Atomic const T * restrict volatile * ),
    13351351        * --?( _Atomic const T * _Atomic restrict volatile * );
    1336 forall( type T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ),
     1352forall( otype T ) _Atomic volatile T * --?( _Atomic volatile T * restrict volatile * ),
    13371353        * --?( _Atomic volatile T * _Atomic restrict volatile * );
    1338 forall( type T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ),
     1354forall( otype T ) _Atomic restrict T * --?( _Atomic restrict T * restrict volatile * ),
    13391355        * --?( _Atomic restrict T * _Atomic restrict volatile * );
    1340 forall( type T ) const volatile T * --?( const volatile T * restrict volatile * ),
     1356forall( otype T ) const volatile T * --?( const volatile T * restrict volatile * ),
    13411357        * --?( const volatile T * _Atomic restrict volatile * );
    1342 forall( type T ) const restrict T * --?( const restrict T * restrict volatile * ),
     1358forall( otype T ) const restrict T * --?( const restrict T * restrict volatile * ),
    13431359        * --?( const restrict T * _Atomic restrict volatile * );
    1344 forall( type T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ),
     1360forall( otype T ) restrict volatile T * --?( restrict volatile T * restrict volatile * ),
    13451361        * --?( restrict volatile T * _Atomic restrict volatile * );
    1346 forall( type T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ),
     1362forall( otype T ) _Atomic const volatile T * --?( _Atomic const volatile T * restrict volatile * ),
    13471363        * --?( _Atomic const volatile T * _Atomic restrict volatile * );
    1348 forall( type T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ),
     1364forall( otype T ) _Atomic const restrict T * --?( _Atomic const restrict T * restrict volatile * ),
    13491365        * --?( _Atomic const restrict T * _Atomic restrict volatile * );
    1350 forall( type T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ),
     1366forall( otype T ) _Atomic restrict volatile T * --?( _Atomic restrict volatile T * restrict volatile * ),
    13511367        * --?( _Atomic restrict volatile T * _Atomic restrict volatile * );
    1352 forall( type T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ),
     1368forall( otype T ) const restrict volatile T * --?( const restrict volatile T * restrict volatile * ),
    13531369        * --?( const restrict volatile T * _Atomic restrict volatile * );
    1354 forall( type T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ),
     1370forall( otype T ) _Atomic const restrict volatile T * --?( _Atomic const restrict volatile T * restrict volatile * ),
    13551371        * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    13561372\end{lstlisting}
     
    13801396\predefined
    13811397\begin{lstlisting}
    1382 forall( type T ) lvalue T *?( T * );
    1383 forall( type T ) _Atomic lvalue T *?( _Atomic T * );
    1384 forall( type T ) const lvalue T *?( const T * );
    1385 forall( type T ) volatile lvalue T *?( volatile T * );
    1386 forall( type T ) restrict lvalue T *?( restrict T * );
    1387 forall( type T ) _Atomic const lvalue T *?( _Atomic const T * );
    1388 forall( type T ) _Atomic volatile lvalue T *?( _Atomic volatile T * );
    1389 forall( type T ) _Atomic restrict lvalue T *?( _Atomic restrict T * );
    1390 forall( type T ) const volatile lvalue T *?( const volatile T * );
    1391 forall( type T ) const restrict lvalue T *?( const restrict T * );
    1392 forall( type T ) restrict volatile lvalue T *?( restrict volatile T * );
    1393 forall( type T ) _Atomic const volatile lvalue T *?( _Atomic const volatile T * );
    1394 forall( type T ) _Atomic const restrict lvalue T *?( _Atomic const restrict T * );
    1395 forall( type T ) _Atomic restrict volatile lvalue T *?( _Atomic restrict volatile T * );
    1396 forall( type T ) const restrict volatile lvalue T *?( const restrict volatile T * );
    1397 forall( type T ) _Atomic const restrict volatile lvalue T *?( _Atomic const restrict volatile T * );
     1398forall( otype T ) lvalue T *?( T * );
     1399forall( otype T ) _Atomic lvalue T *?( _Atomic T * );
     1400forall( otype T ) const lvalue T *?( const T * );
     1401forall( otype T ) volatile lvalue T *?( volatile T * );
     1402forall( otype T ) restrict lvalue T *?( restrict T * );
     1403forall( otype T ) _Atomic const lvalue T *?( _Atomic const T * );
     1404forall( otype T ) _Atomic volatile lvalue T *?( _Atomic volatile T * );
     1405forall( otype T ) _Atomic restrict lvalue T *?( _Atomic restrict T * );
     1406forall( otype T ) const volatile lvalue T *?( const volatile T * );
     1407forall( otype T ) const restrict lvalue T *?( const restrict T * );
     1408forall( otype T ) restrict volatile lvalue T *?( restrict volatile T * );
     1409forall( otype T ) _Atomic const volatile lvalue T *?( _Atomic const volatile T * );
     1410forall( otype T ) _Atomic const restrict lvalue T *?( _Atomic const restrict T * );
     1411forall( otype T ) _Atomic restrict volatile lvalue T *?( _Atomic restrict volatile T * );
     1412forall( otype T ) const restrict volatile lvalue T *?( const restrict volatile T * );
     1413forall( otype T ) _Atomic const restrict volatile lvalue T *?( _Atomic const restrict volatile T * );
    13981414forall( ftype FT ) FT *?( FT * );
    13991415\end{lstlisting}
     
    15101526\begin{rationale}
    15111527\begin{lstlisting}
    1512 type Pair = struct { int first, second; };
     1528otype Pair = struct { int first, second; };
    15131529size_t p_size = sizeof(Pair);           // constant expression
    1514 extern type Rational;@\use{Rational}@
     1530extern otype Rational;@\use{Rational}@
    15151531size_t c_size = sizeof(Rational);       // non-constant expression
    15161532forall(type T) T f(T p1, T p2) {
     
    16361652Consider
    16371653\begin{lstlisting}
    1638 forall( type T | T ?*?( T, T ) ) T square( T );
     1654forall( otype T | T ?*?( T, T ) ) T square( T );
    16391655short s;
    16401656square( s );
     
    16471663A more troubling example is
    16481664\begin{lstlisting}
    1649 forall( type T | ?*?( T, T ) ) T product( T[], int n );
     1665forall( otype T | ?*?( T, T ) ) T product( T[], int n );
    16501666short sa[5];
    16511667product( sa, 5);
     
    17041720        ?+?( _Complex long double, _Complex long double ), ?-?( _Complex long double, _Complex long double );
    17051721
    1706 forall( type T ) T * ?+?( T *, ptrdiff_t ), * ?+?( ptrdiff_t, T * ), * ?-?( T *, ptrdiff_t );
    1707 forall( type T ) _Atomic T * ?+?( _Atomic T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic T * ),
     1722forall( otype T ) T * ?+?( T *, ptrdiff_t ), * ?+?( ptrdiff_t, T * ), * ?-?( T *, ptrdiff_t );
     1723forall( otype T ) _Atomic T * ?+?( _Atomic T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic T * ),
    17081724        * ?-?( _Atomic T *, ptrdiff_t );
    1709 forall( type T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ),
     1725forall( otype T ) const T * ?+?( const T *, ptrdiff_t ), * ?+?( ptrdiff_t, const T * ),
    17101726        * ?-?( const T *, ptrdiff_t );
    1711 forall( type T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ),
     1727forall( otype T ) restrict T * ?+?( restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict T * ),
    17121728        * ?-?( restrict T *, ptrdiff_t );
    1713 forall( type T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ),
     1729forall( otype T ) volatile T * ?+?( volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, volatile T * ),
    17141730        * ?-?( volatile T *, ptrdiff_t );
    1715 forall( type T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ),
     1731forall( otype T ) _Atomic const T * ?+?( _Atomic const T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic const T * ),
    17161732        * ?-?( _Atomic const T *, ptrdiff_t );
    1717 forall( type T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ),
     1733forall( otype T ) _Atomic restrict T * ?+?( _Atomic restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic restrict T * ),
    17181734        * ?-?( _Atomic restrict T *, ptrdiff_t );
    1719 forall( type T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ),
     1735forall( otype T ) _Atomic volatile T * ?+?( _Atomic volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, _Atomic volatile T * ),
    17201736        * ?-?( _Atomic volatile T *, ptrdiff_t );
    1721 forall( type T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ),
     1737forall( otype T ) const restrict T * ?+?( const restrict T *, ptrdiff_t ), * ?+?( ptrdiff_t, const restrict T * ),
    17221738        * ?-?( const restrict T *, ptrdiff_t );
    1723 forall( type T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ),
     1739forall( otype T ) const volatile T * ?+?( const volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, const volatile T * ),
    17241740        * ?-?( const volatile T *, ptrdiff_t );
    1725 forall( type T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ),
     1741forall( otype T ) restrict volatile T * ?+?( restrict volatile T *, ptrdiff_t ), * ?+?( ptrdiff_t, restrict volatile T * ),
    17261742        * ?-?( restrict volatile T *, ptrdiff_t );
    1727 forall( type T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ),
     1743forall( otype T ) _Atomic const restrict T * ?+?( _Atomic const restrict T *, ptrdiff_t ),
    17281744        * ?+?( ptrdiff_t, _Atomic const restrict T * ),
    17291745        * ?-?( _Atomic const restrict T *, ptrdiff_t );
    1730 forall( type T ) ptrdiff_t
     1746forall( otype T ) ptrdiff_t
    17311747        * ?-?( const restrict volatile T *, const restrict volatile T * ),
    17321748        * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * );
     
    20522068
    20532069\begin{lstlisting}
    2054 extern type Rational;@\use{Rational}@
     2070extern otype Rational;@\use{Rational}@
    20552071extern const Rational 0;@\use{0}@
    20562072extern int ?!=?( Rational, Rational );
     
    20952111If 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
    20962112\begin{lstlisting}
    2097 forall( type T ) T cond( int, T, T );
     2113forall( otype T ) T cond( int, T, T );
    20982114forall( dtype D ) void * cond( int, D *, void * ), * cond( int, void *, D * );
    20992115forall( dtype D ) _atomic void * cond(
     
    24552471\predefined
    24562472\begin{lstlisting}
    2457 forall( type T ) T
     2473forall( otype T ) T
    24582474        * ?+=?( T * restrict volatile *, ptrdiff_t ),
    24592475        * ?-=?( T * restrict volatile *, ptrdiff_t ),
    24602476        * ?+=?( T * _Atomic restrict volatile *, ptrdiff_t ),
    24612477        * ?-=?( T * _Atomic restrict volatile *, ptrdiff_t );
    2462 forall( type T ) T _Atomic
     2478forall( otype T ) T _Atomic
    24632479        * ?+=?( T _Atomic * restrict volatile *, ptrdiff_t ),
    24642480        * ?-=?( T _Atomic * restrict volatile *, ptrdiff_t ),
    24652481        * ?+=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t ),
    24662482        * ?-=?( T _Atomic * _Atomic restrict volatile *, ptrdiff_t );
    2467 forall( type T ) T const
     2483forall( otype T ) T const
    24682484        * ?+=?( T const * restrict volatile *, ptrdiff_t ),
    24692485        * ?-=?( T const * restrict volatile *, ptrdiff_t ),
    24702486        * ?+=?( T const * _Atomic restrict volatile *, ptrdiff_t ),
    24712487        * ?-=?( T const * _Atomic restrict volatile *, ptrdiff_t );
    2472 forall( type T ) T restrict
     2488forall( otype T ) T restrict
    24732489        * ?+=?( T restrict * restrict volatile *, ptrdiff_t ),
    24742490        * ?-=?( T restrict * restrict volatile *, ptrdiff_t ),
    24752491        * ?+=?( T restrict * _Atomic restrict volatile *, ptrdiff_t ),
    24762492        * ?-=?( T restrict * _Atomic restrict volatile *, ptrdiff_t );
    2477 forall( type T ) T volatile
     2493forall( otype T ) T volatile
    24782494        * ?+=?( T volatile * restrict volatile *, ptrdiff_t ),
    24792495        * ?-=?( T volatile * restrict volatile *, ptrdiff_t ),
    24802496        * ?+=?( T volatile * _Atomic restrict volatile *, ptrdiff_t ),
    24812497        * ?-=?( T volatile * _Atomic restrict volatile *, ptrdiff_t );
    2482 forall( type T ) T _Atomic const
     2498forall( otype T ) T _Atomic const
    24832499        * ?+=?( T _Atomic const restrict volatile *, ptrdiff_t ),
    24842500        * ?-=?( T _Atomic const restrict volatile *, ptrdiff_t ),
    24852501        * ?+=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t ),
    24862502        * ?-=?( T _Atomic const _Atomic restrict volatile *, ptrdiff_t );
    2487 forall( type T ) T _Atomic restrict
     2503forall( otype T ) T _Atomic restrict
    24882504        * ?+=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ),
    24892505        * ?-=?( T _Atomic restrict * restrict volatile *, ptrdiff_t ),
    24902506        * ?+=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t ),
    24912507        * ?-=?( T _Atomic restrict * _Atomic restrict volatile *, ptrdiff_t );
    2492 forall( type T ) T _Atomic volatile
     2508forall( otype T ) T _Atomic volatile
    24932509        * ?+=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ),
    24942510        * ?-=?( T _Atomic volatile * restrict volatile *, ptrdiff_t ),
    24952511        * ?+=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t ),
    24962512        * ?-=?( T _Atomic volatile * _Atomic restrict volatile *, ptrdiff_t );
    2497 forall( type T ) T const restrict
     2513forall( otype T ) T const restrict
    24982514        * ?+=?( T const restrict * restrict volatile *, ptrdiff_t ),
    24992515        * ?-=?( T const restrict * restrict volatile *, ptrdiff_t ),
    25002516        * ?+=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t ),
    25012517        * ?-=?( T const restrict * _Atomic restrict volatile *, ptrdiff_t );
    2502 forall( type T ) T const volatile
     2518forall( otype T ) T const volatile
    25032519        * ?+=?( T const volatile * restrict volatile *, ptrdiff_t ),
    25042520        * ?-=?( T const volatile * restrict volatile *, ptrdiff_t ),
    25052521        * ?+=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25062522        * ?-=?( T const volatile * _Atomic restrict volatile *, ptrdiff_t );
    2507 forall( type T ) T restrict volatile
     2523forall( otype T ) T restrict volatile
    25082524        * ?+=?( T restrict volatile * restrict volatile *, ptrdiff_t ),
    25092525        * ?-=?( T restrict volatile * restrict volatile *, ptrdiff_t ),
    25102526        * ?+=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25112527        * ?-=?( T restrict volatile * _Atomic restrict volatile *, ptrdiff_t );
    2512 forall( type T ) T _Atomic const restrict
     2528forall( otype T ) T _Atomic const restrict
    25132529        * ?+=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ),
    25142530        * ?-=?( T _Atomic const restrict * restrict volatile *, ptrdiff_t ),
    25152531        * ?+=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t ),
    25162532        * ?-=?( T _Atomic const restrict * _Atomic restrict volatile *, ptrdiff_t );
    2517 forall( type T ) T _Atomic const volatile
     2533forall( otype T ) T _Atomic const volatile
    25182534        * ?+=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ),
    25192535        * ?-=?( T _Atomic const volatile * restrict volatile *, ptrdiff_t ),
    25202536        * ?+=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25212537        * ?-=?( T _Atomic const volatile * _Atomic restrict volatile *, ptrdiff_t );
    2522 forall( type T ) T _Atomic restrict volatile
     2538forall( otype T ) T _Atomic restrict volatile
    25232539        * ?+=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ),
    25242540        * ?-=?( T _Atomic restrict volatile * restrict volatile *, ptrdiff_t ),
    25252541        * ?+=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25262542        * ?-=?( T _Atomic restrict volatile * _Atomic restrict volatile *, ptrdiff_t );
    2527 forall( type T ) T const restrict volatile
     2543forall( otype T ) T const restrict volatile
    25282544        * ?+=?( T const restrict volatile * restrict volatile *, ptrdiff_t ),
    25292545        * ?-=?( T const restrict volatile * restrict volatile *, ptrdiff_t ),
    25302546        * ?+=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t ),
    25312547        * ?-=?( T const restrict volatile * _Atomic restrict volatile *, ptrdiff_t );
    2532 forall( type T ) T _Atomic const restrict volatile
     2548forall( otype T ) T _Atomic const restrict volatile
    25332549        * ?+=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ),
    25342550        * ?-=?( T _Atomic const restrict volatile * restrict volatile *, ptrdiff_t ),
     
    28422858This 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.
    28432859\begin{lstlisting}
    2844 forall( type T ) struct Pair { T a, b;
     2860forall( otype T ) struct Pair { T a, b;
    28452861} mkPair( T, T ); // illegal
    28462862\end{lstlisting}
     
    28672883If this restriction were lifted, it would be possible to write
    28682884\begin{lstlisting}
    2869 forall( type T ) T * alloc( void );@\use{alloc}@ int *p = alloc();
     2885forall( otype T ) T * alloc( void );@\use{alloc}@ int *p = alloc();
    28702886\end{lstlisting}
    28712887Here \lstinline$alloc()$ would receive \lstinline$int$ as an inferred argument, and return an
     
    28762892\lstinline$T$:
    28772893\begin{lstlisting}
    2878 forall( type T ) T * alloc( T initial_value );@\use{alloc}@
     2894forall( otype T ) T * alloc( T initial_value );@\use{alloc}@
    28792895\end{lstlisting}
    28802896\end{rationale}
     
    28992915\begin{lstlisting}
    29002916int fi( int );
    2901 forall( type T ) T fT( T );
     2917forall( otype T ) T fT( T );
    29022918\end{lstlisting}
    29032919\lstinline$fi()$ takes an \lstinline$int$ and returns an \lstinline$int$. \lstinline$fT()$ takes a
     
    29052921\begin{lstlisting}
    29062922int (*pfi )( int ) = fi;
    2907 forall( type T ) T (*pfT )( T ) = fT;
     2923forall( otype T ) T (*pfT )( T ) = fT;
    29082924\end{lstlisting}
    29092925\lstinline$pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$ is not polymorphic, but the function it points at is.
     
    29122928        return pfi;
    29132929}
    2914 forall( type T ) T (*fvpfT( void ))( T ) {
     2930forall( otype T ) T (*fvpfT( void ))( T ) {
    29152931        return pfT;
    29162932}
     
    29182934\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.
    29192935\begin{lstlisting}
    2920 forall( type T ) int ( *fTpfi( T ) )( int );
    2921 forall( type T ) T ( *fTpfT( T ) )( T );
    2922 forall( type T, type U ) U ( *fTpfU( T ) )( U );
     2936forall( otype T ) int ( *fTpfi( T ) )( int );
     2937forall( otype T ) T ( *fTpfT( T ) )( T );
     2938forall( otype T, otype U ) U ( *fTpfU( T ) )( U );
    29232939\end{lstlisting}
    29242940\lstinline$fTpfi()$ is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer.
     
    29302946\lstinline$char *$.
    29312947\begin{lstlisting}
    2932 forall( type T, type U, type V ) U * f( T *, U, V * const );
    2933 forall( type U, type V, type W ) U * g( V *, U, W * const );
     2948forall( otype T, otype U, otype V ) U * f( T *, U, V * const );
     2949forall( otype U, otype V, otype W ) U * g( V *, U, W * const );
    29342950\end{lstlisting}
    29352951The functions \lstinline$f()$ and \lstinline$g()$ have compatible types.
     
    29392955Replacing every \(f_i\) by \(g_i\) in \(f\) gives
    29402956\begin{lstlisting}
    2941 forall( type V, type U, type W ) U * f( V *, U, W * const );
     2957forall( otype V, otype U, otype W ) U * f( V *, U, W * const );
    29422958\end{lstlisting} which has a return type and parameter list that is compatible with \(g\).
    29432959\begin{rationale}
     
    31273143\examples
    31283144\begin{lstlisting}
    3129 forall( type T | T ?*?( T, T ))@\use{?*?}@
     3145forall( otype T | T ?*?( T, T ))@\use{?*?}@
    31303146T square( T val ) {@\impl{square}@
    31313147        return val + val;
    31323148}
    3133 context summable( type T ) {@\impl{summable}@
     3149trait summable( otype T ) {@\impl{summable}@
    31343150        T ?+=?( T *, T );@\use{?+=?}@
    31353151        const T 0;@\use{0}@
    31363152};
    3137 context list_of( type List, type Element ) {@\impl{list_of}@
     3153trait list_of( otype List, otype Element ) {@\impl{list_of}@
    31383154        Element car( List );
    31393155        List cdr( List );
     
    31423158        int is_nil( List );
    31433159};
    3144 context sum_list( type List, type Element | summable( Element ) | list_of( List, Element ) ) {};
     3160trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {};
    31453161\end{lstlisting}
    31463162\lstinline$sum_list$ contains seven declarations, which describe a list whose elements can be added up.
     
    32043220Incomplete type declarations allow compact mutually-recursive types.
    32053221\begin{lstlisting}
    3206 type t1; // incomplete type declaration
    3207 type t2 = struct { t1 * p; ... };
    3208 type t1 = struct { t2 * p; ... };
     3222otype t1; // incomplete type declaration
     3223otype t2 = struct { t1 * p; ... };
     3224otype t1 = struct { t2 * p; ... };
    32093225\end{lstlisting}
    32103226Without them, mutual recursion could be handled by declaring mutually recursive structures, then initializing the types to those structures.
    32113227\begin{lstlisting}
    32123228struct s1;
    3213 type t2 = struct s2 { struct s1 * p; ... };
    3214 type t1 = struct s1 { struct s2 * p; ... };
     3229otype t2 = struct s2 { struct s1 * p; ... };
     3230otype t1 = struct s1 { struct s2 * p; ... };
    32153231\end{lstlisting}
    32163232This introduces extra names, and may force the programmer to cast between the types and their implementations.
     
    32673283This prevents the declaration of types that contain each other.
    32683284\begin{lstlisting}
    3269 type t1;
    3270 type t2 = t1; // illegal: incomplete type t1
    3271 type t1 = t2;
     3285otype t1;
     3286otype t2 = t1; // illegal: incomplete type t1
     3287otype t1 = t2;
    32723288\end{lstlisting}
    32733289
     
    32763292 types}.
    32773293\begin{lstlisting}
    3278 extern type Huge; // extended-precision integer type
    3279 type Rational = struct {
     3294extern otype Huge; // extended-precision integer type
     3295otype Rational = struct {
    32803296        Huge numerator, denominator;    // illegal
    32813297};
     
    33163332\begin{lstlisting}
    33173333#include <stdlib.h>
    3318 T * new( type T ) { return ( T * )malloc( sizeof( T) ); };
     3334T * new( otype T ) { return ( T * )malloc( sizeof( T) ); };
    33193335@\ldots@ int * ip = new( int );
    33203336\end{lstlisting}
     
    33273343Since type declarations create new types, instances of types are always passed by value.
    33283344\begin{lstlisting}
    3329 type A1 = int[2];
     3345otype A1 = int[2];
    33303346void f1( A1 a ) { a[0] = 0; };
    3331 typedef int A2[2];
     3347otypedef int A2[2];
    33323348void f2( A2 a ) { a[0] = 0; };
    33333349A1 v1;
     
    33463362That unit might contain the declarations
    33473363\begin{lstlisting}
    3348 type Complex = struct { float re, im; };@\impl{Complex}@
     3364otype Complex = struct { float re, im; };@\impl{Complex}@
    33493365Complex cplx_i = { 0.0, 1.0 };@\impl{cplx_i}@
    33503366float abs( Complex c ) {@\impl{abs( Complex )}@
     
    33553371
    33563372\begin{lstlisting}
    3357 type Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.
     3373otype Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.
    33583374Time_of_day ?+?( Time_of_day t1, int seconds ) {@\impl{?+?}@
    33593375        return (( int)t1 + seconds ) % 86400;
     
    34293445\examples
    34303446\begin{lstlisting}
    3431 context s( type T ) {
     3447trait s( otype T ) {
    34323448        T a, b;
    34333449} struct impl { int left, right; } a = { 0, 0 };
    3434 type Pair | s( Pair ) = struct impl;
     3450otype Pair | s( Pair ) = struct impl;
    34353451Pair b = { 1, 1 };
    34363452\end{lstlisting}
     
    34403456\lstinline$Pair b$ is compulsory because there is no \lstinline$struct impl b$ to construct a value from.
    34413457\begin{lstlisting}
    3442 context ss( type T ) {
     3458trait ss( otype T ) {
    34433459        T clone( T );
    34443460        void munge( T * );
    34453461}
    3446 type Whatsit | ss( Whatsit );@\use{Whatsit}@
    3447 type Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@
     3462otype Whatsit | ss( Whatsit );@\use{Whatsit}@
     3463otype Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@
    34483464        Whatsit; // anonymous member
    34493465        int extra;
     
    34663482Default functions and objects are subject to the normal scope rules.
    34673483\begin{lstlisting}
    3468 type T = @\ldots@;
     3484otype T = @\ldots@;
    34693485T a_T = @\ldots@;               // Default assignment used.
    34703486T ?=?( T *, T );
     
    37353751The assertion ``\lstinline$scalar( Complex )$'' should be read as ``type \lstinline$Complex$ is scalar''.
    37363752\begin{lstlisting}
    3737 context scalar( type T ) {@\impl{scalar}@
     3753trait scalar( otype T ) {@\impl{scalar}@
    37383754        int !?( T );
    37393755        int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T );
     
    37453761This is equivalent to inheritance of specifications.
    37463762\begin{lstlisting}
    3747 context arithmetic( type T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@
     3763trait arithmetic( otype T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@
    37483764        T +?( T ), -?( T );
    37493765        T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T );
     
    37543770\define{integral types}.
    37553771\begin{lstlisting}
    3756 context integral( type T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@
     3772trait integral( otype T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@
    37573773        T ~?( T );
    37583774        T ?&?( T, T ), ?|?( T, T ), ?^?( T, T );
     
    37683784The only operation that can be applied to all modifiable lvalues is simple assignment.
    37693785\begin{lstlisting}
    3770 context m_lvalue( type T ) {@\impl{m_lvalue}@
     3786trait m_lvalue( otype T ) {@\impl{m_lvalue}@
    37713787        T ?=?( T *, T );
    37723788};
     
    37783794Scalars can also be incremented and decremented.
    37793795\begin{lstlisting}
    3780 context m_l_scalar( type T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@
     3796trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@
    37813797        T ?++( T * ), ?--( T * );@\use{scalar}@@\use{m_lvalue}@
    37823798        T ++?( T * ), --?( T * );
     
    37873803Note that this results in the ``inheritance'' of \lstinline$scalar$ along both paths.
    37883804\begin{lstlisting}
    3789 context m_l_arithmetic( type T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@
     3805trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@
    37903806        T ?/=?( T *, T ), ?*=?( T *, T );@\use{m_l_scalar}@@\use{arithmetic}@
    37913807        T ?+=?( T *, T ), ?-=?( T *, T );
    37923808};
    3793 context m_l_integral( type T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@
     3809trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@
    37943810        T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );@\use{m_l_arithmetic}@
    37953811        T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );@\use{integral}@
     
    38113827\lstinline$arithmetic$, so these operators cannot be consolidated in \lstinline$scalar$.
    38123828\begin{lstlisting}
    3813 context pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@
     3829trait pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@
    38143830        P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int );
    38153831        ptrdiff_t ?-?( P, P );
    38163832};
    3817 context m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@
     3833trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@
    38183834        P ?+=?( P *, long int ), ?-=?( P *, long int );
    38193835        P ?=?( P *, void * );
     
    38273843``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''.
    38283844\begin{lstlisting}
    3829 context ptr_to( type P | pointer( P ), type T ) {@\impl{ptr_to}@@\use{pointer}@
     3845trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@
    38303846        lvalue T *?( P );
    38313847        lvalue T ?[?]( P, long int );
    38323848};
    3833 context ptr_to_const( type P | pointer( P ), type T ) {@\impl{ptr_to_const}@
     3849trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
    38343850        const lvalue T *?( P );
    38353851        const lvalue T ?[?]( P, long int );@\use{pointer}@
    38363852};
    3837 context ptr_to_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_volatile}@
     3853trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
    38383854        volatile lvalue T *?( P );
    38393855        volatile lvalue T ?[?]( P, long int );@\use{pointer}@
    38403856};
    3841 context ptr_to_const_volatile( type P | pointer( P ), type T ) }@\impl{ptr_to_const_volatile}@
     3857trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@
    38423858        const volatile lvalue T *?( P );@\use{pointer}@
    38433859        const volatile lvalue T ?[?]( P, long int );
     
    38493865``\lstinline$ptr_to$'' specifications.
    38503866\begin{lstlisting}
    3851 context 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}@ {
     3867trait 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}@ {
    38523868        P ?=?( P *, T * );
    38533869        T * ?=?( T **, P );
    38543870};
    3855 context 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}@) {
     3871trait 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}@) {
    38563872        P ?=?( P *, const T * );
    38573873        const T * ?=?( const T **, P );
    38583874};
    3859 context 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}@
     3875trait 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}@
    38603876        P ?=?( P *, volatile T * );
    38613877        volatile T * ?=?( volatile T **, P );
    38623878};
    3863 context 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}@
     3879trait 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}@
    38643880                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}@
    38653881        P ?=?( P *, const volatile T * );
     
    38713887An 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.
    38723888\begin{lstlisting}
    3873 context 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 ) ) {
     3889trait 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 ) ) {
    38743890        MyP ?=?( MyP *, CP );
    38753891        CP ?=?( CP *, MyP );
     
    39043920C and \CFA have an extra, non-obvious comparison operator: ``\lstinline$!$'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise.
    39053921\begin{lstlisting}
    3906 context comparable( type T ) {
     3922trait comparable( otype T ) {
    39073923        const T 0;
    39083924        int compare( T, T );
    39093925}
    3910 forall( type T | comparable( T ) ) int ?<?( T l, T r ) {
     3926forall( otype T | comparable( T ) ) int ?<?( T l, T r ) {
    39113927        return compare( l, r ) < 0;
    39123928}
    39133929// ... similarly for <=, ==, >=, >, and !=.
    3914 forall( type T | comparable( T ) ) int !?( T operand ) {
     3930forall( otype T | comparable( T ) ) int !?( T operand ) {
    39153931        return !compare( operand, 0 );
    39163932}
     
    39243940Similarly, a complete integral type would provide integral operations based on integral assignment operations.
    39253941\begin{lstlisting}
    3926 context arith_base( type T ) {
     3942trait arith_base( otype T ) {
    39273943        const T 1;
    39283944        T ?+=?( T *, T ), ?-=?( T *, T ), ?*=?( T *, T ), ?/=?( T *, T );
    39293945}
    3930 forall( type T | arith_base( T ) ) T ?+?( T l, T r ) {
     3946forall( otype T | arith_base( T ) ) T ?+?( T l, T r ) {
    39313947        return l += r;
    39323948}
    3933 forall( type T | arith_base( T ) ) T ?++( T * operand ) {
     3949forall( otype T | arith_base( T ) ) T ?++( T * operand ) {
    39343950        T temporary = *operand;
    39353951        *operand += 1;
    39363952        return temporary;
    39373953}
    3938 forall( type T | arith_base( T ) ) T ++?( T * operand ) {
     3954forall( otype T | arith_base( T ) ) T ++?( T * operand ) {
    39393955        return *operand += 1;
    39403956}
    39413957// ... similarly for -, --, *, and /.
    3942 context int_base( type T ) {
     3958trait int_base( otype T ) {
    39433959        T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );
    39443960        T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );
    39453961}
    3946 forall( type T | int_base( T ) ) T ?&?( T l, T r ) {
     3962forall( otype T | int_base( T ) ) T ?&?( T l, T r ) {
    39473963        return l &= r;
    39483964}
Note: See TracChangeset for help on using the changeset viewer.