Ignore:
Timestamp:
May 7, 2025, 9:48:24 PM (5 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
ed0a7e5
Parents:
2c065ed
Message:

half way through proofreading array chapter

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/mike_brooks_MMath/array.tex

    r2c065ed r579427b  
    1717though using a new style of generic parameter.
    1818\begin{cfa}
    19 @array( float, 99 )@ x;                                 $\C[2.75in]{// x contains 99 floats}$
    20 \end{cfa}
    21 Here, the arguments to the @array@ type are @float@ (element type) and @99@ (length).
    22 When this type is used as a function parameter, the type-system requires that a call's argument is a perfect match.
     19@array( float, 99 )@ x;                                 $\C[2.5in]{// x contains 99 floats}$
     20\end{cfa}
     21Here, the arguments to the @array@ type are @float@ (element type) and @99@ (dimension).
     22When this type is used as a function parameter, the type-system requires the argument is a perfect match.
    2323\begin{cfa}
    2424void f( @array( float, 42 )@ & p ) {}   $\C{// p accepts 42 floats}$
    2525f( x );                                                                 $\C{// statically rejected: type lengths are different, 99 != 42}$
    26 
    2726test2.cfa:3:1 error: Invalid application of existing declaration(s) in expression.
    2827Applying untyped:  Name: f ... to:  Name: x
    2928\end{cfa}
    30 Here, the function @f@'s parameter @p@ is declared with length 42.
    31 However, the call @f( x )@ is invalid, because @x@'s length is @99@, which does not match @42@.
    32 
    33 A function declaration can be polymorphic over these @array@ arguments by using the \CFA @forall@ declaration prefix.
     29Function @f@'s parameter expects an array with dimension 42, but the argument dimension 99 does not match.
     30
     31A function can be polymorphic over @array@ arguments using the \CFA @forall@ declaration prefix.
    3432\begin{cfa}
    3533forall( T, @[N]@ )
     
    3836}
    3937g( x, 0 );                                                              $\C{// T is float, N is 99, dynamic subscript check succeeds}$
    40 g( x, 1000 );                                                   $\C{// T is float, N is 99, dynamic subscript check fails}\CRT$
    41 
     38g( x, 1000 );                                                   $\C{// T is float, N is 99, dynamic subscript check fails}$
    4239Cforall Runtime error: subscript 1000 exceeds dimension range [0,99) $for$ array 0x555555558020.
    4340\end{cfa}
    44 Function @g@ takes an arbitrary type parameter @T@ and a \emph{dimension parameter} @N@.
    45 A dimension parameter represents a to-be-determined count of elements, managed by the type system.
    46 The call @g( x, 0 )@ is valid because @g@ accepts any length of array, where the type system infers @float@ for @T@ and length @99@ for @N@.
    47 Inferring values for @T@ and @N@ is implicit.
    48 Furthermore, in this case, the runtime subscript @x[0]@ (parameter @i@ being @0@) in @g@ is valid because 0 is in the dimension range $[0,99)$ of argument @x@.
    49 However, the call @g( x, 1000 )@ is also accepted through compile time;
    50 however, this case's subscript, @x[1000]@, generates an error, because @1000@ is outside the dimension range $[0,99)$ of argument @x@.
     41Function @g@ takes an arbitrary type parameter @T@ and an unsigned integer \emph{dimension} @N@.
     42The dimension represents a to-be-determined number of elements, managed by the type system, where 0 represents an empty array.
     43The type system implicitly infers @float@ for @T@ and @99@ for @N@.
     44Furthermore, the runtime subscript @x[0]@ (parameter @i@ being @0@) in @g@ is valid because 0 is in the dimension range $[0,99)$ for argument @x@.
     45The call @g( x, 1000 )@ is also accepted at compile time.
     46However, the subscript, @x[1000]@, generates a runtime error, because @1000@ is outside the dimension range $[0,99)$ of argument @x@.
    5147In general, the @forall( ..., [N] )@ participates in the user-relevant declaration of the name @N@, which becomes usable in parameter/return declarations and within a function.
    5248The syntactic form is chosen to parallel other @forall@ forms:
    5349\begin{cfa}
    54 forall( @[N]@ ) ...     $\C[1.5in]{// dimension}$
    55 forall( T ) ...         $\C{// value datatype (formerly, "otype")}$
    56 forall( T & ) ...       $\C{// opaque datatype (formerly, "dtype")}\CRT$
     50forall( @[N]@ ) ...     $\C{// dimension}$
     51forall( T ) ...         $\C{// value datatype}$
     52forall( T & ) ...       $\C{// opaque datatype}$
    5753\end{cfa}
    5854% The notation @array(thing, N)@ is a single-dimensional case, giving a generic type instance.
     
    6359\begin{cfa}
    6460forall( [N] )
    65 void declDemo( ... ) {
    66         float x1[N];                                            $\C{// built-in type ("C array")}$
    67         array(float, N) x2;                                     $\C{// type from library}$
    68 }
    69 \end{cfa}
    70 Both of the locally-declared array variables, @x1@ and @x2@, have 42 elements, each element being a @float@.
    71 The two variables have identical size and layout; they both encapsulate 42-float stack allocations, with no additional ``bookkeeping'' allocations or headers.
     61void f( ... ) {
     62        float x1[@N@];                                          $\C{// C array, no subscript checking}$
     63        array(float, N) x2;                                     $\C{// \CFA array, subscript checking}\CRT$
     64}
     65\end{cfa}
     66Both of the stack declared array variables, @x1@ and @x2@, have 42 elements, each element being a @float@.
     67The two variables have identical size and layout, with no additional ``bookkeeping'' allocations or headers.
     68The C array, @x1@, has no subscript checking, while \CFA array, @x2@, does.
    7269Providing this explicit generic approach requires a significant extension to the \CFA type system to support a full-feature, safe, efficient (space and time) array-type, which forms the foundation for more complex array forms in \CFA.
    73 In all following discussion, ``C array'' means the types like that of @x@ and ``\CFA array'' means the standard-library @array@ type (instantiations), like the type of @x2@.
    74 
    75 Admittedly, the @array@ library type for @x2@ is syntactically different from its C counterpart.
    76 A future goal (TODO xref) is to provide the new @array@ features with syntax approaching C's (declaration style of @x1@).
     70In all following discussion, ``C array'' means types like @x1@ and ``\CFA array'' means types like @x2@.
     71
     72A future goal is to provide the new @array@ features with syntax approaching C's (declaration style of @x1@).
    7773Then, the library @array@ type could be removed, giving \CFA a largely uniform array type.
    78 At present, the C-syntax @array@ is only partially supported, so the generic @array@ is used exclusively in the thesis;
    79 feature support and C compatibility are revisited in Section ? TODO.
     74At present, the C-syntax @array@ is only partially supported, so the generic @array@ is used exclusively in the thesis.
    8075
    8176My contributions in this chapter are:
    82 \begin{enumerate}
     77\begin{enumerate}[leftmargin=*]
    8378\item A type system enhancement that lets polymorphic functions and generic types be parameterized by a numeric value: @forall( [N] )@.
    84 \item Provide a length-checked array-type in the \CFA standard library, where the array's length is statically managed and dynamically valued.
     79\item Provide a dimension/subscript-checked array-type in the \CFA standard library, where the array's length is statically managed and dynamically valued.
    8580\item Provide argument/parameter passing safety for arrays and subscript safety.
    86 \item TODO: general parking...
    8781\item Identify the interesting specific abilities available by the new @array@ type.
    8882\item Where there is a gap concerning this feature's readiness for prime-time, identification of specific workable improvements that are likely to close the gap.
     
    9084
    9185
     86\begin{comment}
    9287\section{Dependent Typing}
    9388
    94 General dependent typing allows the type system to encode arbitrary predicates (\eg behavioural specifications for functions),
    95 which is an anti-goal for my work.
     89General dependent typing allows a type system to encode arbitrary predicates, \eg behavioural specifications for functions, which is an anti-goal for my work.
    9690Firstly, this application is strongly associated with pure functional languages,
    9791where a characterization of the return value (giving it a precise type, generally dependent upon the parameters)
     
    10195Secondly, TODO: bash Rust.
    10296TODO: cite the crap out of these claims.
     97\end{comment}
    10398
    10499
    105100\section{Features Added}
    106101
    107 This section shows more about using the \CFA array and dimension parameters, demonstrating their syntax and semantics by way of motivating examples.
     102This section shows more about using the \CFA array and dimension parameters, demonstrating syntax and semantics by way of motivating examples.
    108103As stated, the core capability of the new array is tracking all dimensions within the type system, where dynamic dimensions are represented using type variables.
    109104
    110105By declaring type variables at the front of object declarations, an array dimension is lexically referenceable where it is needed.
    111 For example, a declaration can share one length, @N@, among a pair of parameters and the return,
    112 meaning that it requires both input arrays to be of the same length, and guarantees that the result is of that length as well.
     106For example, a declaration can share one length, @N@, among a pair of parameters and return type, meaning the input arrays and return array are the same length.
    113107\lstinput{10-17}{hello-array.cfa}
    114108Function @f@ does a pointwise comparison of its two input arrays, checking if each pair of numbers is within half a percent of each other, returning the answers in a newly allocated @bool@ array.
    115 The dynamic allocation of the @ret@ array, by the library @alloc@ function,
     109The dynamic allocation of the @ret@ array uses the library @alloc@ function,
    116110\begin{cfa}
    117111forall( T & | sized(T) )
     
    120114}
    121115\end{cfa}
    122 uses the parameterized dimension information implicitly within its @sizeof@ determination, and casts the return type.
    123 Note that @alloc@ only sees one whole type for its @T@ (which is @f@'s @array(bool, N)@); this type's size is a computation based on @N@.
     116which captures the parameterized dimension information implicitly within its @sizeof@ determination, and casts the return type.
     117Note, @alloc@ only sees the whole type for its @T@, @array(bool, N)@, where this type's size is a computation based on @N@.
    124118This example illustrates how the new @array@ type plugs into existing \CFA behaviour by implementing necessary \emph{sized} assertions needed by other types.
    125119(\emph{sized} implies a concrete \vs abstract type with a runtime-available size, exposed as @sizeof@.)
     
    129123\lstinput{30-43}{hello-array.cfa}
    130124\lstinput{45-48}{hello-array.cfa}
    131 \caption{\lstinline{f} Harness}
    132 \label{f:fHarness}
     125\caption{\lstinline{f} Example}
     126\label{f:fExample}
    133127\end{figure}
    134128
    135 \VRef[Figure]{f:fHarness} shows a harness that uses function @f@, illustrating how dynamic values are fed into the @array@ type.
     129\VRef[Figure]{f:fExample} shows an example using function @f@, illustrating how dynamic values are fed into the @array@ type.
    136130Here, the dimension of arrays @x@, @y@, and @result@ is specified from a command-line value, @dim@, and these arrays are allocated on the stack.
    137131Then the @x@ array is initialized with decreasing values, and the @y@ array with amounts offset by constant @0.005@, giving relative differences within tolerance initially and diverging for later values.
     
    144138
    145139In summary:
    146 \begin{itemize}
     140\begin{itemize}[leftmargin=*]
    147141\item
    148142@[N]@ within a @forall@ declares the type variable @N@ to be a managed length.
    149143\item
    150 @N@ can be used an expression of type @size_t@ within the declared function body.
     144@N@ can be used in an expression with type @size_t@ within the function body.
    151145\item
    152146The value of an @N@-expression is the acquired length, derived from the usage site, \ie generic declaration or function call.
     
    158152\begin{enumerate}[leftmargin=*]
    159153\item
    160 The \CC template @N@ can only be compile-time value, while the \CFA @N@ may be a runtime value.
    161 % agreed, though already said
     154The \CC template @N@ can only be a compile-time value, while the \CFA @N@ may be a runtime value.
    162155\item
    163156\CC does not allow a template function to be nested, while \CFA lets its polymorphic functions to be nested.
    164 % why is this important?
    165 \item
     157Hence, \CC precludes a simple form of information hiding.
     158\item
     159\label{p:DimensionPassing}
    166160The \CC template @N@ must be passed explicitly at the call, unless @N@ has a default value, even when \CC can deduct the type of @T@.
    167161The \CFA @N@ is part of the array type and passed implicitly at the call.
     
    169163% mycode/arrr/thesis-examples/check-peter/cs-cpp.cpp, v2
    170164\item
    171 \CC cannot have an array of references, but can have an array of pointers.
     165\CC cannot have an array of references, but can have an array of @const@ pointers.
    172166\CC has a (mistaken) belief that references are not objects, but pointers are objects.
    173167In the \CC example, the arrays fall back on C arrays, which have a duality with references with respect to automatic dereferencing.
     
    178172% https://stackoverflow.com/questions/922360/why-cant-i-make-a-vector-of-references
    179173\item
     174\label{p:ArrayCopy}
    180175C/\CC arrays cannot be copied, while \CFA arrays can be copied, making them a first-class object (although array copy is often avoided for efficiency).
    181176% fixed by comparing to std::array
    182177% mycode/arrr/thesis-examples/check-peter/cs-cpp.cpp, v10
    183178\end{enumerate}
    184 TODO: settle Mike's concerns with this comparison (perhaps, remove)
     179The \CC template @array@ type mitigates points \VRef[]{p:DimensionPassing} and \VRef[]{p:ArrayCopy}, but it is also trying to accomplish a similar mechanism to \CFA @array@.
    185180
    186181\begin{figure}
     
    226221Just as the first example in \VRef[Section]{s:ArrayIntro} shows a compile-time rejection of a length mismatch,
    227222so are length mismatches stopped when they involve dimension parameters.
    228 While \VRef[Figure]{f:fHarness} shows successfully calling a function @f@ expecting two arrays of the same length,
     223While \VRef[Figure]{f:fExample} shows successfully calling a function @f@ expecting two arrays of the same length,
    229224\begin{cfa}
    230225array( bool, N ) & f( array( float, N ) &, array( float, N ) & );
     
    246241The same argument safety and the associated implicit communication of array length occurs.
    247242Preexisting \CFA allowed aggregate types to be generalized with type parameters, enabling parameterizing of element types.
    248 Now, \CFA also allows parameterizing them by length.
    249 Doing so gives a refinement of C's ``flexible array member'' pattern[TODO: cite ARM 6.7.2.1 pp18]\cite{arr:gnu-flex-mbr}.
    250 While a C flexible array member can only occur at the end of the enclosing structure,
    251 \CFA allows length-parameterized array members to be nested at arbitrary locations.
    252 This flexibility, in turn, allows for multiple array members.
     243This has been extended to allow parameterizing by dimension.
     244Doing so gives a refinement of C's ``flexible array member''~\cite[\S~6.7.2.1.18]{C11}.
     245\begin{cfa}
     246struct S {
     247        ...
     248        double d []; // incomplete array type => flexible array member
     249} * s = malloc( sizeof( struct S ) + sizeof( double [10] ) );
     250\end{cfa}
     251which creates a VLA of size 10 @double@s at the end of the structure.
     252A C flexible array member can only occur at the end of a structure;
     253\CFA allows length-parameterized array members to be nested at arbitrary locations, with intervening member declarations.
    253254\lstinput{10-15}{hello-accordion.cfa}
    254255The structure has course- and student-level metatdata (their respective field names) and a position-based preferences' matrix.
    255256Its layout has the starting offset of @studentIds@ varying according to the generic parameter @C@, and the offset of @preferences@ varying according to both generic parameters.
    256257
    257 \VRef[Figure]{f:checkHarness} shows a program main using @School@ and results with different array sizes.
     258\VRef[Figure]{f:checkExample} shows a program main using @School@ and results with different array sizes.
    258259The @school@ variable holds many students' course-preference forms.
    259260It is on the stack and its initialization does not use any casting or size arithmetic.
     
    285286\end{cquote}
    286287
    287 \caption{\lstinline{School} harness, input and output}
    288 \label{f:checkHarness}
     288\caption{\lstinline{School} Example, Input and Output}
     289\label{f:checkExample}
    289290\end{figure}
    290291
    291292When a function operates on a @School@ structure, the type system handles its memory layout transparently.
    292293\lstinput{30-37}{hello-accordion.cfa}
    293 In the example, this @getPref@ function answers, for the student at position @is@, what is the position of its @pref@\textsuperscript{th}-favoured class?
     294In the example, function @getPref@ returns, for the student at position @is@, what is the position of their @pref@\textsuperscript{th}-favoured class?
    294295
    295296
     
    324325
    325326The repurposed heavy equipment is
    326 \begin{itemize}
     327\begin{itemize}[leftmargin=*]
    327328\item
    328329        Resolver provided values for a used declaration's type-system variables,
     
    348349int main() {
    349350        thing( @10@ ) x;  f( x );  $\C{// prints 10, [4]}$
    350         thing( 100 ) y;  f( y );  $\C{// prints 100}$
    351         return 0;
     351        thing( @100@ ) y;  f( y );  $\C{// prints 100}$
    352352}
    353353\end{cfa}
    354354This example has:
    355 \begin{enumerate}
     355\begin{enumerate}[leftmargin=*]
    356356\item
    357357        The symbol @N@ being declared as a type variable (a variable of the type system).
     
    369369Because the box pass handles a type's size as its main datum, the encoding is chosen to use it.
    370370The production and recovery are then straightforward.
    371 \begin{itemize}
     371\begin{itemize}[leftmargin=*]
    372372\item
    373373        The value $n$ is encoded as a type whose size is $n$.
    374374\item
    375         Given a dimension expression $e$, produce type @char[@$e$@]@ to represent it.
     375        Given a dimension expression $e$, produce an internal type @char[@$e$@]@ to represent it.
    376376        If $e$ evaluates to $n$ then the encoded type has size $n$.
    377377\item
     
    389389}
    390390int main() {
    391         thing( char[@10@] ) x;  f( x );  $\C{// prints 10, [4]}$
    392         thing( char[100] ) y;  f( y );  $\C{// prints 100}$
    393         return 0;
     391        thing( @char[10]@ ) x;  f( x );  $\C{// prints 10, [4]}$
     392        thing( @char[100]@ ) y;  f( y );  $\C{// prints 100}$
    394393}
    395394\end{cfa}
    396395Observe:
    397 \begin{enumerate}
     396\begin{enumerate}[leftmargin=*]
    398397\item
    399398        @N@ is now declared to be a type.
    400         It is declared to be \emph{sized} (by the @*@), meaning that the box pass shall do its @sizeof(N)@--@__sizeof_N@ extra parameter and expression translation.
     399        It is declared to be \emph{sized} (by the @*@), meaning that the box pass shall do its @sizeof(N)@$\rightarrow$@__sizeof_N@ extra parameter and expression translation.
    401400\item
    402401        @thing(N)@ is a type; the argument to the generic @thing@ is a type (type variable).
     
    404403        The @sout...@ expression (being an application of the @?|?@ operator) has a second argument that is an ordinary expression.
    405404\item
    406         The type of variable @x@ is another @thing(-)@ type; the argument to the generic @thing@ is a type (array type of bytes, @char@).
     405        The type of variable @x@ is another @thing(-)@ type; the argument to the generic @thing@ is a type (array type of bytes, @char[@$e$@]@).
    407406\end{enumerate}
    408407
     
    415414        struct __conc_thing_10 {} x;  f( @10@, &x );  $\C{// prints 10, [4]}$
    416415        struct __conc_thing_100 {} y;  f( @100@, &y );  $\C{// prints 100}$
    417         return 0;
    418416}
    419417\end{cfa}
    420418Observe:
    421 \begin{enumerate}
     419\begin{enumerate}[leftmargin=*]
    422420\item
    423421        The type parameter @N@ is gone.
     
    427425        The @sout...@ expression (being an application of the @?|?@ operator) has a regular variable (parameter) usage for its second argument.
    428426\item
    429         Information about the particular @thing@ instantiation (value 10) has moved, from the type, to a regular function-call argument.
     427        Information about the particular @thing@ instantiation (value 10) is moved, from the type, to a regular function-call argument.
    430428\end{enumerate}
    431429At the end of the desugaring and downstream processing, the original C idiom of ``pass both a length parameter and a pointer'' has been reconstructed.
     
    433431The compiler's action produces the more complex form, which if handwritten, would be error-prone.
    434432
    435 Back at the compiler front end, the parsing changes AST schema extensions and validation rules for enabling the sugared user input.
    436 \begin{itemize}
     433At the compiler front end, the parsing changes AST schema extensions and validation rules for enabling the sugared user input.
     434\begin{itemize}[leftmargin=*]
    437435\item
    438436        Recognize the form @[N]@ as a type-variable declaration within a @forall@.
     
    440438        Have the new brand of type-variable, \emph{Dimension}, in the AST form of a type-variable, to represent one parsed from @[-]@.
    441439\item
    442         Allow a type variable to occur in an expression.  Validate (after parsing) that only dimension-branded type variables are used here.
     440        Allow a type variable to occur in an expression.  Validate (after parsing) that only dimension-branded type-variables are used here.
    443441\item
    444442        Allow an expression to occur in type-argument position.  Brand the resulting type argument as a dimension.
     
    457455\label{s:ArrayTypingC}
    458456
    459 Essential in giving a guarantee of accurate length is the compiler's ability
    460 to reject a program that presumes to mishandle length.
    461 By contrast, most discussion so far dealt with communicating length,
    462 from one party who knows it, to another who is willing to work with any given length.
    463 For scenarios where the concern is a mishandled length,
    464 the interaction is between two parties who both claim to know something about it.
    465 Such a scenario occurs in this pure C fragment, which today's C compilers accept:
    466 \begin{cfa}
    467 int n = @42@;
    468 float x[n];
    469 float (*xp)[@999@] = &x;
     457Essential in giving a guarantee of accurate length is the compiler's ability to reject a program that presumes to mishandle length.
     458By contrast, most discussion so far deals with communicating length, from one party who knows it, to another willing to work with any given length.
     459For scenarios where the concern is a mishandled length, the interaction is between two parties who both claim to know something about it.
     460
     461C and \CFA can check when working with two static values.
     462\begin{cfa}
     463enum { n = 42 };
     464float x[@n@];   // or just 42
     465float (*xp1)[@42@] = &x;    // accept
     466float (*xp2)[@999@] = &x;   // reject
     467warning: initialization of 'float (*)[999]' from incompatible pointer type 'float (*)[42]'
     468\end{cfa}
     469When a variable is involved, C and \CFA take two different approaches.
     470Today's C compilers accept the following without warning.
     471\begin{cfa}
     472static const int n = 42;
     473float x[@n@];
     474float (* xp)[@999@] = &x; $\C{// should be static rejection here}$
    470475(*xp)[@500@]; $\C{// in "bound"?}$
    471476\end{cfa}
    472477Here, the array @x@ has length 42, while a pointer to it (@xp@) claims length 999.
    473 So, while the subscript of @xp@ at position 500 is out of bound of its referent @x@,
     478So, while the subscript of @xp@ at position 500 is out of bound with its referent @x@,
    474479the access appears in-bound of the type information available on @xp@.
    475 Truly, length is being mishandled in the previous step,
    476 where the type-carried length information on @x@ is not compatible with that of @xp@.
    477 
    478 The \CFA new-array rejects the analogous case:
    479 \begin{cfa}
    480 int n = @42@;
    481 array(float, n) x;
    482 array(float, 999) * xp = x; $\C{// static rejection here}$
    483 (*xp)[@500@]; $\C{// runtime check vs len 999}$
    484 \end{cfa}
    485 The way the \CFA array is implemented, the type analysis of this case reduces to a case similar to the earlier C version.
     480In fact, length is being mishandled in the previous step, where the type-carried length information on @x@ is not compatible with that of @xp@.
     481
     482In \CFA, I choose to reject this C example at the point where the type-carried length information on @x@ is not compatible with that of @xp@, and correspondingly, its array counterpart at the same location:
     483\begin{cfa}
     484static const int n = 42;
     485array( float, @n@ ) x;
     486array( float, @999@ ) * xp = &x; $\C{// static rejection here}$
     487(*xp)[@500@]; $\C{// runtime check passes}$
     488\end{cfa}
     489The way the \CFA array is implemented, the type analysis for this case reduces to a case similar to the earlier C version.
    486490The \CFA compiler's compatibility analysis proceeds as:
    487491\begin{itemize}[parsep=0pt]
    488492\item
    489         Is @array(float, 999)@ type-compatible with @array(float, n)@?
    490 \item
    491         Is @arrayX(float, char[999])@ type-compatible with @arrayX(float, char[n])@?\footnote{
    492                 Here, \lstinline{arrayX} represents the type that results
    493                 from desugaring the \lstinline{array} type
    494                 into a type whose generic parameters are all types.
    495                 This presentation elides the noisy fact that
    496                 \lstinline{array} is actually a macro for something bigger;
    497                 the reduction to \lstinline{char[-]} still proceeds as sketched.}
    498 \item
    499         Is @char[999]@ type-compatible with @char[n]@?
     493        Is @array( float, 999 )@ type-compatible with @array( float, n )@?
     494\item
     495        Is desugared @array( float, char[999] )@ type-compatible with desugared @array( float, char[n] )@?
     496%               \footnote{
     497%               Here, \lstinline{arrayX} represents the type that results from desugaring the \lstinline{array} type into a type whose generic parameters are all types.
     498%               This presentation elides the noisy fact that \lstinline{array} is actually a macro for something bigger;
     499%               the reduction to \lstinline{char [-]} still proceeds as sketched.}
     500\item
     501        Is internal type @char[999]@ type-compatible with internal type @char[n]@?
    500502\end{itemize}
    501 To achieve the necessary \CFA rejections meant rejecting the corresponding C case, which is not backward compatible.
    502 There are two complementary mitigations for this incompatibility.
    503 
    504 First, a simple recourse is available to a programmer who intends to proceed
    505 with the statically unsound assignment.
    506 This situation might arise if @n@ were known to be 999,
    507 rather than 42, as in the introductory examples.
    508 The programmer can add a cast in the \CFA code.
    509 \begin{cfa}
    510 xp = @(float (*)[999])@ &x;
    511 \end{cfa}
    512 This addition causes \CFA to accept, because now, the programmer has accepted blame.
    513 This addition is benign in plain C, because the cast is valid, just unnecessary there.
    514 Moreover, the addition can even be seen as appropriate ``eye candy,''
    515 marking where the unchecked length knowledge is used.
    516 Therefore, a program being onboarded to \CFA can receive a simple upgrade,
    517 to satisfy the \CFA rules (and arguably become clearer),
    518 without giving up its validity to a plain C compiler.
    519 
    520 Second, the incompatibility only affects types like pointer-to-array,
    521 which are are infrequently used in C.
    522 The more common C idiom for aliasing an array is to use a pointer-to-first-element type,
    523 which does not participate in the \CFA array's length checking.\footnote{
     503The answer is false because, in general, the value of @n@ is unknown at compile time, and hence, an error is raised.
     504For safety, it makes sense to reject the corresponding C case, which is a non-backwards compatible change.
     505There are two mitigations for this incompatibility.
     506
     507First, a simple recourse is available in a situation where @n@ is \emph{known} to be 999 by using a cast.
     508\begin{cfa}
     509float (* xp)[999] = @(float (*)[999])@&x;
     510\end{cfa}
     511The cast means the programmer has accepted blame.
     512Moreover, the cast is ``eye candy'' marking where the unchecked length knowledge is used.
     513Therefore, a program being onboarded to \CFA requires some upgrading to satisfy the \CFA rules (and arguably become clearer), without giving up its validity to a plain C compiler.
     514Second, the incompatibility only affects types like pointer-to-array, which are infrequently used in C.
     515The more common C idiom for aliasing an array is to use a pointer-to-first-element type, which does not participate in the \CFA array's length checking.\footnote{
    524516        Notably, the desugaring of the \lstinline{array} type avoids letting any \lstinline{-[-]} type decay,
    525517        in order to preserve the length information that powers runtime bound-checking.}
    526 Therefore, the frequency of needing to upgrade legacy C code (as discussed in the first mitigation)
    527 is anticipated to be low.
    528 
    529 Because the incompatibility represents a low cost to a \CFA onboarding effort
    530 (with a plausible side benefit of linting the original code for a missing annotation),
    531 no special measures were added to retain the compatibility.
    532 It would be possible to flag occurrences of @-[-]@ types that come from @array@ desugaring,
    533 treating those with stricter \CFA rules, while treating others with classic C rules.
    534 If future lessons from C project onboarding warrant it,
    535 this special compatibility measure can be added.
    536 
    537 Having allowed that both the initial C example's check
    538 \begin{itemize}
    539         \item
    540                 Is @float[999]@ type-compatible with @float[n]@?
    541 \end{itemize}
    542 and the second \CFA example's induced check
    543 \begin{itemize}
    544         \item
    545                 Is @char[999]@ type-compatible with @char[n]@?
    546 \end{itemize}
    547 shall have the same answer, (``no''),
    548 discussion turns to how I got the \CFA compiler to produce this answer.
    549 In its preexisting form, it produced a (buggy) approximation of the C rules.
    550 To implement the new \CFA rules, I took the syntactic recursion a step further, obtaining,
    551 in both cases:
    552 \begin{itemize}
    553         \item
    554                 Is @999@ compatible with @n@?
    555 \end{itemize}
    556 This compatibility question applies to a pair of expressions, where the earlier implementation were to types.
    557 Such an expression-compatibility question is a new addition to the \CFA compiler.
    558 Note, these questions only arise in the context of dimension expressions on (C) array types.
    559 
    560 TODO: ensure these compiler implementation matters are treated under \CFA compiler background:
    561 type unification,
    562 cost calculation,
    563 GenPoly.
    564 
    565 The relevant technical component of the \CFA compiler is the type unification procedure within the type resolver.
    566 I added rules for continuing this unification into expressions that occur within types.
    567 It is still fundamentally doing \emph{type} unification
    568 because it is participating in binding type variables,
    569 and not participating in binding any variables that stand in for expression fragments
    570 (for there is no such sort of variable in \CFA's analysis.)
    571 An unfortunate fact about the \CFA compiler's preexisting implementation is that
    572 type unification suffers from two forms of duplication.
    573 
    574 The first duplication has (many of) the unification rules stated twice.
    575 As a result, my additions for dimension expressions are stated twice.
    576 The extra statement of the rules occurs in the @GenPoly@ module,
    577 where concrete types like @array(int, 5)@\footnote{
    578         Again, the presentation is simplified
    579         by leaving the \lstinline{array} macro unexpanded.}
    580 are lowered into corresponding C types @struct __conc_array_1234@ (the suffix being a generated index).
    581 In this case, the struct's definition contains fields that hardcode the argument values of @float@ and @5@.
    582 The next time an @array(-,-)@ concrete instance is encountered, it checks if the previous @struct __conc_array_1234@ is suitable for it.
    583 Yes, for another occurrence of @array(int, 5)@;
    584 no, for either @array(rational(int), 5)@ or @array(int, 42)@.
    585 By the last example, this phase must ``reject''
    586 the hypothesis that it should reuse the dimension-5 instance's C-lowering for a dimension-42 instance.
    587 
    588 The second duplication has unification (proper) being invoked at two stages of expression resolution.
    589 As a result, my added rule set needs to handle more cases than the preceding discussion motivates.
    590 In the program
    591 \begin{cfa}
    592 void @f@( double );
    593 forall( T & ) void @f@( T & );
    594 void g( int n ) {
    595         array( float, n + 1 ) x;
    596         f(x);   // overloaded
    597 }
    598 \end{cfa}
    599 when resolving the function call, @g@, the first unification stage
    600 compares the type @T@ of the parameter with @array( float, n + 1 )@, of the argument.
    601 TODO: finish.
    602 
    603 The actual rules for comparing two dimension expressions are conservative.
    604 To answer, ``yes, consider this pair of expressions to be matching,''
    605 is to imply, ``all else being equal, allow an array with length calculated by $e_1$
    606 to be passed to a function expecting a length-$e_2$ array.''\footnote{
    607         TODO: Deal with directionality, that I'm doing exact-match, no ``at least as long as,'' no subtyping.
    608         Should it be an earlier scoping principle?  Feels like it should matter in more places than here.}
    609 So, a ``yes'' answer must represent a guarantee that both expressions evaluate the
    610 same result, while a ``no'' can tolerate ``they might, but we're not sure'',
    611 provided that practical recourses are available
    612 to let programmers express better knowledge.
    613 The new rule-set in the current release is, in fact, extremely conservative.
    614 I chose to keep things simple,
    615 and allow future needs to drive adding additional complexity, within the new framework.
    616 
    617 For starters, the original motivating example's rejection
    618 is not based on knowledge that
    619 the @xp@ length of (the literal) 999 is value-unequal to
    620 the (obvious) runtime value of the variable @n@, which is the @x@ length.
    621 Rather, the analysis assumes a variable's value can be anything,
    622 and so there can be no guarantee that its value is 999.
    623 So, a variable and a literal can never match.
    624 
    625 Two occurrences of the same literal value are obviously a fine match.
    626 For two occurrences of the same variable, more information is needed.
    627 For example, this one is fine
    628 \begin{cfa}
    629 void f( const int n ) {
    630         float x[n];
    631         float (*xp)[n] = x;   // accept
    632 }
    633 \end{cfa}
    634 while this one is not:
    635 \begin{cfa}
     518Therefore, the need to upgrade legacy C code is low.
     519Finally, if this incompatibility is a problem onboarding C programs to \CFA, it is should be possible to change the C type check to a warning rather than an error, acting as a \emph{lint} of the original code for a missing type annotation.
     520
     521To handle two occurrences of the same variable, more information is needed, \eg, this is fine,
     522\begin{cfa}
     523int n = 42;
     524float x[@n@];
     525float (*xp)[@n@] = x;   // accept
     526\end{cfa}
     527where @n@ remains fixed across a contiguous declaration context.
     528However, intervening dynamic statement cause failures.
     529\begin{cfa}
     530int n = 42;
     531float x[@n@];
     532@n@ = 999; // dynamic change
     533float (*xp)[@n@] = x;   // reject
     534\end{cfa}
     535However, side-effects can occur in a contiguous declaration context.
     536\begin{cquote}
     537\setlength{\tabcolsep}{20pt}
     538\begin{tabular}{@{}ll@{}}
     539\begin{cfa}
     540// compile unit 1
     541extern int @n@;
     542extern float g();
    636543void f() {
    637         int n = 42;
    638         float x[n];
    639         n = 999;
    640         float (*xp)[n] = x;   // reject
    641 }
    642 \end{cfa}
    643 Furthermore, the fact that the first example sees @n@ as @const@
    644 is not actually sufficient.
    645 In this example, @f@'s length expression's declaration is as @const@ as it can be,
    646 yet its value still changes between the two invocations:
    647 \begin{cquote}
    648 \setlength{\tabcolsep}{15pt}
    649 \begin{tabular}{@{}ll@{}}
    650 \begin{cfa}
    651 // compile unit 1
    652 void g();
    653 void f( const int & const nr ) {
    654         float x[nr];
    655         g();    // change n
    656         @float (*xp)[nr] = x;@   // reject
     544        float x[@n@] = { g() };
     545        float (*xp)[@n@] = x;   // reject
    657546}
    658547\end{cfa}
     
    660549\begin{cfa}
    661550// compile unit 2
    662 static int n = 42;
     551int @n@ = 42;
    663552void g() {
    664         n = 99;
    665 }
    666 
    667 f( n );
     553        @n@ = 99;
     554}
     555
     556
    668557\end{cfa}
    669558\end{tabular}
     
    671560The issue here is that knowledge needed to make a correct decision is hidden by separate compilation.
    672561Even within a translation unit, static analysis might not be able to provide all the information.
    673 
    674 My rule set also respects a traditional C feature: In spite of the several limitations of the C rules
    675 accepting cases that produce different values, there are a few mismatches that C stops.
    676 C is quite precise when working with two static values.
    677 \begin{cfa}
    678 enum { fortytwo = 42 };
    679 float x[fortytwo];
    680 float (*xp1)[42] = &x;    // accept
    681 float (*xp2)[999] = &x;   // reject
    682 \end{cfa}
    683 My \CFA rules agree with C's on these cases.
     562However, if the example uses @const@, the check is possible.
     563\begin{cquote}
     564\setlength{\tabcolsep}{20pt}
     565\begin{tabular}{@{}ll@{}}
     566\begin{cfa}
     567// compile unit 1
     568extern @const@ int n;
     569extern float g();
     570void f() {
     571        float x[n] = { g() };
     572        float (*xp)[n] = x;   // reject
     573}
     574\end{cfa}
     575&
     576\begin{cfa}
     577// compile unit 2
     578@const@ int n = 42;
     579void g() {
     580        @n = 99@; // allowed
     581}
     582
     583
     584\end{cfa}
     585\end{tabular}
     586\end{cquote}
    684587
    685588In summary, the new rules classify expressions into three groups:
    686589\begin{description}
    687590\item[Statically Evaluable]
    688         Expressions for which a specific value can be calculated (conservatively)
    689         at compile-time.
    690         A preexisting \CFA compiler module defines which literals, enumerators, and expressions qualify,
    691         and evaluates them.
     591        Expressions for which a specific value can be calculated (conservatively) at compile-time.
     592        A preexisting \CFA compiler module defines which literals, enumerators, and expressions qualify and evaluates them.
    692593\item[Dynamic but Stable]
    693594        The value of a variable declared as @const@, including a @const@ parameter.
    694595\item[Potentially Unstable]
    695596        The catch-all category.  Notable examples include:
    696         any function-call result, @float x[foo()];@,
    697         the particular function-call result that is a pointer dereference, @void f(const int * n)@ @{ float x[*n]; }@, and
    698         any use of a reference-typed variable.
     597        any function-call result, @float x[foo()]@, the particular function-call result that is a pointer dereference, @void f(const int * n)@ @{ float x[*n]; }@, and any use of a reference-typed variable.
    699598\end{description}
    700599Within these groups, my \CFA rules are:
    701 \begin{itemize}
     600\begin{itemize}[leftmargin=*]
    702601\item
    703602        Accept a Statically Evaluable pair, if both expressions have the same value.
     
    710609\end{itemize}
    711610The traditional C rules are:
    712 \begin{itemize}
     611\begin{itemize}[leftmargin=*]
    713612\item
    714613        Reject a Statically Evaluable pair, if the expressions have two different values.
     
    716615        Otherwise, accept.
    717616\end{itemize}
     617\VRef[Figure]{f:DimexprRuleCompare} gives a case-by-case comparison of the consequences of these rule sets.
     618It demonstrates that the \CFA false alarms occur in the same cases as C treats unsafe.
     619It also shows that C-incompatibilities only occur in cases that C treats unsafe.
    718620
    719621\begin{figure}
     
    746648                where \lstinline{expr1} and \lstinline{expr2} are meta-variables varying according to the row's Case.
    747649                Each row's claim applies to other harnesses too, including,
    748                 \begin{itemize}
     650                \begin{itemize}[leftmargin=*]
    749651                \item
    750652                        calling a function with a parameter like \lstinline{x} and an argument of the \lstinline{xp} type,
     
    762664                The table treats symbolic identity (Same/Different on rows)
    763665                apart from value equality (Equal/Unequal on columns).
    764                 \begin{itemize}
     666                \begin{itemize}[leftmargin=*]
    765667                \item
    766668                        The expressions \lstinline{1}, \lstinline{0+1} and \lstinline{n}
     
    781683\end{figure}
    782684
    783 
    784 \VRef[Figure]{f:DimexprRuleCompare} gives a case-by-case comparison of the consequences of these rule sets.
    785 It demonstrates that the \CFA false alarms occur in the same cases as C treats unsafe.
    786 It also shows that C-incompatibilities only occur in cases that C treats unsafe.
    787 
    788 
    789 The conservatism of the new rule set can leave a programmer needing a recourse,
    790 when needing to use a dimension expression whose stability argument
    791 is more subtle than current-state analysis.
     685\begin{comment}
     686Given that the above check
     687\begin{itemize}
     688        \item
     689        Is internal type @char[999]@ type-compatible with internal type @char[n]@?
     690\end{itemize}
     691answers false, discussion turns to how I got the \CFA compiler to produce this answer.
     692In its preexisting form, the type system had a buggy approximation of the C rules.
     693To implement the new \CFA rules, I added one further step.
     694\begin{itemize}
     695        \item
     696                Is @999@ compatible with @n@?
     697\end{itemize}
     698This question applies to a pair of expressions, where the earlier question applies to types.
     699An expression-compatibility question is a new addition to the \CFA compiler, and occurs in the context of dimension expressions, and possibly enumerations assigns, which must be unique.
     700
     701% TODO: ensure these compiler implementation matters are treated under \CFA compiler background: type unification, cost calculation, GenPoly.
     702
     703The relevant technical component of the \CFA compiler is the standard type-unification within the type resolver.
     704\begin{cfa}
     705example
     706\end{cfa}
     707I added rules for continuing this unification into expressions that occur within types.
     708It is still fundamentally doing \emph{type} unification because it is participating in binding type variables, and not participating in binding any variables that stand in for expression fragments (for there is no such sort of variable in \CFA's analysis.)
     709An unfortunate fact about the \CFA compiler's preexisting implementation is that type unification suffers from two forms of duplication.
     710
     711In detail, the first duplication has (many of) the unification rules stated twice.
     712As a result, my additions for dimension expressions are stated twice.
     713The extra statement of the rules occurs in the @GenPoly@ module, where concrete types like @array( int, 5 )@\footnote{
     714        Again, the presentation is simplified
     715        by leaving the \lstinline{array} macro unexpanded.}
     716are lowered into corresponding C types @struct __conc_array_1234@ (the suffix being a generated index).
     717In this case, the struct's definition contains fields that hardcode the argument values of @float@ and @5@.
     718The next time an @array( -, - )@ concrete instance is encountered, it checks if the previous @struct __conc_array_1234@ is suitable for it.
     719Yes, for another occurrence of @array( int, 5 )@;
     720no, for examples like @array( int, 42 )@ or @array( rational(int), 5 )@.
     721In the first example, it must reject the reuse hypothesis for a dimension-@5@ and a dimension-@42@ instance.
     722
     723The second duplication has unification (proper) being invoked at two stages of expression resolution.
     724As a result, my added rule set needs to handle more cases than the preceding discussion motivates.
     725In the program
     726\begin{cfa}
     727void @f@( double ); // overload
     728forall( T & ) void @f@( T & ); // overload
     729void g( int n ) {
     730        array( float, n + 1 ) x;
     731        f(x);   // overloaded
     732}
     733\end{cfa}
     734when resolving a function call to @g@, the first unification stage compares the type @T@ of the parameter with @array( float, n + 1 )@, of the argument.
     735\PAB{TODO: finish.}
     736
     737The actual rules for comparing two dimension expressions are conservative.
     738To answer, ``yes, consider this pair of expressions to be matching,''
     739is to imply, ``all else being equal, allow an array with length calculated by $e_1$
     740to be passed to a function expecting a length-$e_2$ array.''\footnote{
     741        TODO: Deal with directionality, that I'm doing exact-match, no ``at least as long as,'' no subtyping.
     742        Should it be an earlier scoping principle?  Feels like it should matter in more places than here.}
     743So, a ``yes'' answer must represent a guarantee that both expressions evaluate the
     744same result, while a ``no'' can tolerate ``they might, but we're not sure'',
     745provided that practical recourses are available
     746to let programmers express better knowledge.
     747The new rule-set in the current release is, in fact, extremely conservative.
     748I chose to keep things simple,
     749and allow future needs to drive adding additional complexity, within the new framework.
     750
     751For starters, the original motivating example's rejection is not based on knowledge that the @xp@ length of (the literal) 999 is value-unequal to the (obvious) runtime value of the variable @n@, which is the @x@ length.
     752Rather, the analysis assumes a variable's value can be anything, and so there can be no guarantee that its value is 999.
     753So, a variable and a literal can never match.
     754
     755TODO: Discuss the interaction of this dimension hoisting with the challenge of extra unification for cost calculation
     756\end{comment}
     757
     758The conservatism of the new rule set can leave a programmer needing a recourse, when needing to use a dimension expression whose stability argument is more subtle than current-state analysis.
    792759This recourse is to declare an explicit constant for the dimension value.
    793 Consider these two dimension expressions,
    794 whose reuses are rejected by the blunt current-state rules:
    795 \begin{cfa}
    796 void f( int & nr, const int nv ) {
    797         float x[nr];
    798         float (*xp)[nr] = &x;   // reject: nr varying (no references)
    799         float y[nv + 1];
    800         float (*yp)[nv + 1] = &y;   // reject: ?+? unpredictable (no functions)
     760Consider these two dimension expressions, whose uses are rejected by the blunt current-state rules:
     761\begin{cfa}
     762void f( int @&@ nr, @const@ int nv ) {
     763        float x[@nr@];
     764        float (*xp)[@nr@] = &x;   // reject: nr varying (no references)
     765        float y[@nv + 1@];
     766        float (*yp)[@nv + 1@] = &y;   // reject: ?+? unpredictable (no functions)
    801767}
    802768\end{cfa}
    803769Yet, both dimension expressions are reused safely.
    804 The @nr@ reference is never written, not volatile
    805 and control does not leave the function between the uses.
    806 The name @?+?@ resolves to a function that is quite predictable.
    807 Here, the programmer can add the constant declarations (cast does not work):
     770The @nr@ reference is never written, not volatile meaning no implicit code (load) between declarations, and control does not leave the function between the uses.
     771As well, the build-in @?+?@ function is predictable.
     772To make these cases work, the programmer must add the follow constant declarations (cast does not work):
    808773\begin{cfa}
    809774void f( int & nr, const int nv ) {
     
    819784achieved by adding a superfluous ``snapshot it as of now'' directive.
    820785
    821 The snapshotting trick is also used by the translation, though to achieve a different outcome.
     786The snapshot trick is also used by the \CFA translation, though to achieve a different outcome.
    822787Rather obviously, every array must be subscriptable, even a bizarre one:
    823788\begin{cfa}
    824 array( float, rand(10) ) x;
    825 x[0];  // 10% chance of bound-check failure
    826 \end{cfa}
    827 Less obvious is that the mechanism of subscripting is a function call,
    828 which must communicate length accurately.
    829 The bound-check above (callee logic) must use the actual allocated length of @x@,
    830 without mistakenly reevaluating the dimension expression, @rand(10)@.
     789array( float, @rand(10)@ ) x;
     790x[@0@];  // 10% chance of bound-check failure
     791\end{cfa}
     792Less obvious is that the mechanism of subscripting is a function call, which must communicate length accurately.
     793The bound-check above (callee logic) must use the actual allocated length of @x@, without mistakenly reevaluating the dimension expression, @rand(10)@.
    831794Adjusting the example to make the function's use of length more explicit:
    832795\begin{cfa}
    833 forall ( T * )
    834 void f( T * x ) { sout | sizeof(*x); }
     796forall( T * )
     797void f( T * x ) { sout | sizeof( *x ); }
    835798float x[ rand(10) ];
    836799f( x );
     
    840803void f( size_t __sizeof_T, void * x ) { sout | __sizeof_T; }
    841804\end{cfa}
    842 the translation must call the dimension argument twice:
     805the translation calls the dimension argument twice:
    843806\begin{cfa}
    844807float x[ rand(10) ];
    845808f( rand(10), &x );
    846809\end{cfa}
    847 Rather, the translation is:
     810The correct form is:
    848811\begin{cfa}
    849812size_t __dim_x = rand(10);
     
    851814f( __dim_x, &x );
    852815\end{cfa}
    853 The occurrence of this dimension hoisting during translation was in the preexisting \CFA compiler.
    854 But its cases were buggy, particularly with determining, ``Can hoisting the expression be skipped here?'', for skipping this hoisting is clearly desirable in some cases.
    855 For example, when the programmer has already done so manually. \PAB{I don't know what this means.}
     816Dimension hoisting already existed in the \CFA compiler.
     817But its was buggy, particularly with determining, ``Can hoisting the expression be skipped here?'', for skipping this hoisting is clearly desirable in some cases.
     818For example, when a programmer has already hoisted to perform an optimiation to prelude duplicate code (expression) and/or expression evaluation.
    856819In the new implementation, these cases are correct, harmonized with the accept/reject criteria.
    857 
    858 TODO: Discuss the interaction of this dimension hoisting with the challenge of extra unification for cost calculation
    859820
    860821
     
    863824
    864825A multidimensional array implementation has three relevant levels of abstraction, from highest to lowest, where the array occupies \emph{contiguous memory}.
    865 \begin{enumerate}
     826\begin{enumerate}[leftmargin=*]
    866827\item
    867828Flexible-stride memory:
     
    11001061Preexisting \CFA mechanisms achieve this requirement, but with poor performance.
    11011062Furthermore, advanced array users need an exception to the basic mechanism, which does not occur with other aggregates.
    1102 Hence, arrays introduce subleties in supporting an element's lifecycle.
     1063Hence, arrays introduce subtleties in supporting an element's lifecycle.
    11031064
    11041065The preexisting \CFA support for contained-element lifecycle is based on recursive occurrences of the object-type (@otype@) pseudo-trait.
     
    13191280The @worker@ type is designed this way to work with the threading system.
    13201281A thread type forks a thread at the end of each constructor and joins with it at the start of each destructor.
    1321 But a @worker@ cannot begin its forked-thead work without knowing its @id@.
     1282But a @worker@ cannot begin its forked-thread work without knowing its @id@.
    13221283Therefore, there is a conflict between the implicit actions of the builtin @thread@ type and a user's desire to defer these actions.
    13231284
     
    14601421
    14611422The \CFA array and the field of ``array language'' comparators all leverage dependent types to improve on the expressiveness over C and Java, accommodating examples such as:
    1462 \begin{itemize}
     1423\begin{itemize}[leftmargin=*]
    14631424\item a \emph{zip}-style operation that consumes two arrays of equal length
    14641425\item a \emph{map}-style operation whose produced length matches the consumed length
     
    15441505The details in this presentation aren't meant to be taken too precisely as suggestions for how it should look in \CFA.
    15451506But the example shows these abilities:
    1546 \begin{itemize}
     1507\begin{itemize}[leftmargin=*]
    15471508\item a built-in way (the @is_enum@ trait) for a generic routine to require enumeration-like information about its instantiating type
    15481509\item an implicit implementation of the trait whenever a user-written enum occurs (@weekday@'s declaration implies @is_enum@)
Note: See TracChangeset for help on using the changeset viewer.