Changeset 343c8be


Ignore:
Timestamp:
Jun 25, 2024, 9:26:16 PM (3 days ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
d5efcb7
Parents:
089b39e1 (diff), d96d4f0 (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

Location:
doc
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.sty

    r089b39e1 r343c8be  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue May 28 07:56:52 2024
    14 %% Update Count     : 658
     13%% Last Modified On : Mon Jun 24 08:03:28 2024
     14%% Update Count     : 659
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    187187
    188188\newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.}
    189 \newcommand{\eg}{\EG\CheckCommaColon}
     189\newcommand{\eg}{\EG\protect\CheckCommaColon}
    190190
    191191\newcommand{\IE}{\abbrevFont{i}.\abbrevFont{e}.}
    192 \newcommand{\ie}{\IE\CheckCommaColon}
     192\newcommand{\ie}{\IE\protect\CheckCommaColon}
    193193
    194194\newcommand{\ETC}{\abbrevFont{etc}}
    195 \newcommand{\etc}{\ETC\CheckPeriod}
     195\newcommand{\etc}{\ETC\protect\CheckPeriod}
    196196
    197197\newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}}
    198 \newcommand{\etal}{\ETAL\CheckPeriod}
     198\newcommand{\etal}{\ETAL\protect\CheckPeriod}
    199199
    200200\newcommand{\VIZ}{\abbrevFont{viz}}
    201 \newcommand{\viz}{\VIZ\CheckPeriod}
     201\newcommand{\viz}{\VIZ\protect\CheckPeriod}
    202202
    203203\newcommand{\VS}{\abbrevFont{vs}}
    204 \newcommand{\vs}{\VS\CheckPeriod}
     204\newcommand{\vs}{\VS\protect\CheckPeriod}
    205205
    206206\newenvironment{cquote}{%
  • doc/LaTeXmacros/common.tex

    r089b39e1 r343c8be  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue May 28 07:41:21 2024
    14 %% Update Count     : 665
     13%% Last Modified On : Mon Jun 24 08:01:50 2024
     14%% Update Count     : 667
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    188188
    189189\newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.}
    190 \newcommand{\eg}{\EG\CheckCommaColon}
     190\newcommand{\eg}{\EG\protect\CheckCommaColon}
    191191
    192192\newcommand{\IE}{\abbrevFont{i}.\abbrevFont{e}.}
    193 \newcommand{\ie}{\IE\CheckCommaColon}
     193\newcommand{\ie}{\IE\protect\CheckCommaColon}
    194194
    195195\newcommand{\ETC}{\abbrevFont{etc}}
    196 \newcommand{\etc}{\ETC\CheckPeriod}
     196\newcommand{\etc}{\ETC\protect\CheckPeriod}
    197197
    198198\newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}}
    199 \newcommand{\etal}{\ETAL\CheckPeriod}
     199\newcommand{\etal}{\ETAL\protect\CheckPeriod}
    200200
    201201\newcommand{\VIZ}{\abbrevFont{viz}}
    202 \newcommand{\viz}{\VIZ\CheckPeriod}
     202\newcommand{\viz}{\VIZ\protect\CheckPeriod}
    203203
    204204\newcommand{\VS}{\abbrevFont{vs}}
    205 \newcommand{\vs}{\VS\CheckPeriod}
     205\newcommand{\vs}{\VS\protect\CheckPeriod}
    206206
    207207\newenvironment{cquote}{%
  • doc/theses/jiada_liang_MMath/CFAenum.tex

    r089b39e1 r343c8be  
    391391The unnamed enumeration provides the gravitational-constant enumerator @G@.
    392392Function @surfaceGravity@ uses the @with@ clause to remove @p@ qualification from fields @mass@ and @radius@.
    393 The program main uses @SizeE@ to obtain the number of enumerators in @Planet@, and safely converts the random value into a @Planet@ enumerator.
    394 The resulting random orbital-body is used in a \CFA @choose@ statement.
    395 The enumerators in the @case@ clause use position for testing.
    396 The prints use @labelE@ to print an enumerator's label.
    397 Finally, a loop iterates through the planets computing the weight on each planet for a given earth mass.
    398 The print statement does an equality comparison with an enumeration variable and enumerator.
     393The program main uses the pseudo function @countof@ to obtain the number of enumerators in @Planet@, and safely converts the random value into a @Planet@ enumerator using @fromInt@.
     394The resulting random orbital-body is used in a @choose@ statement.
     395The enumerators in the @case@ clause use enumerator position for testing.
     396The prints use @label@ to print an enumerator's name.
     397Finally, a loop enumerates through the planets computing the weight on each planet for a given earth mass.
     398The print statement does an equality comparison with an enumeration variable and enumerator (@p == MOON@).
    399399
    400400\begin{figure}
     
    402402\begin{cfa}
    403403struct MR { double mass, radius; };
    404 enum( @MR@ ) Planet {
     404enum( @MR@ ) Planet {                                           $\C{// typed enumeration}$
    405405        //                      mass (kg)   radius (km)
    406406        MERCURY = { 0.330_E24, 2.4397_E6 },
    407407        VENUS      = { 4.869_E24, 6.0518_E6 },
    408408        EARTH       = { 5.976_E24, 6.3781_E6 },
    409         MOON        = { 7.346_E22, 1.7380_E6 }, $\C{// not a planet}$
     409        MOON        = { 7.346_E22, 1.7380_E6 }, $\C{// not a planet}$
    410410        MARS         = { 0.642_E24, 3.3972_E6 },
    411411        JUPITER    = { 1898._E24, 71.492_E6 },
     
    413413        URANUS    = { 86.86_E24, 25.559_E6 },
    414414        NEPTUNE  = { 102.4_E24, 24.746_E6 },
    415 };
    416 enum( double ) { G = 6.6743_E-11 }; $\C{// universal gravitational constant (m3 kg-1 s-2)}$
     415        PLUTO       = { 1.303_E22, 1.1880_E6 }, $\C{// not a planet}$
     416};
     417enum( double ) { G = 6.6743_E-11 };                     $\C{// universal gravitational constant (m3 kg-1 s-2)}$
    417418static double surfaceGravity( Planet p ) @with( p )@ {
    418         return G * mass / ( radius \ 2 ); $\C{// exponentiation}$
     419        return G * mass / ( radius @\@ 2 );             $\C{// no qualification, exponentiation}$
    419420}
    420421static double surfaceWeight( Planet p, double otherMass ) {
     
    422423}
    423424int main( int argc, char * argv[] ) {
    424         if ( argc != 2 ) exit | "Usage: " | argv[0] | "earth-weight";
     425        if ( argc != 2 ) @exit@ | "Usage: " | argv[0] | "earth-weight";  // terminate program
    425426        double earthWeight = convert( argv[1] );
    426427        double earthMass = earthWeight / surfaceGravity( EARTH );
    427 
    428         Planet p = @fromInt@( prng( @SizeE@(Planet) ) ); $\C{// select a random orbiting body}$
    429         @choose( p )@ {
     428        Planet rp = @fromInt@( prng( @countof@( Planet ) ) ); $\C{// select random orbiting body}$
     429        @choose( rp )@ {                                                $\C{// implicit breaks}$
    430430          case MERCURY, VENUS, EARTH, MARS:
    431                 sout | @labelE( p )@ | "is a rocky planet";
    432           @case JUPITER, SATURN, URANUS, NEPTUNE:@
    433                 sout | labelE( p ) | "is a gas-giant planet";
     431                sout | @label( rp )@ | "is a rocky planet";
     432          case JUPITER, SATURN, URANUS, NEPTUNE:
     433                sout | label( rp ) | "is a gas-giant planet";
    434434          default:
    435                 sout | labelE( p ) | "is not a planet";
     435                sout | label( rp ) | "is not a planet";
    436436        }
    437         for ( @p; Planet@ ) {
    438                 sout | "Your weight on" | (@p == MOON@ ? "the" : "") | labelE(p)
    439                            | "is" | wd( 1,1, surfaceWeight( p, earthMass ) ) | "kg";
     437        for ( @p; Planet@ ) {                                   $\C{// enumerate}$
     438                sout | "Your weight on" | ( @p == MOON@ ? "the" : " " ) | label( p )
     439                           | "is" | wd( 1,1,  surfaceWeight( p, earthMass ) ) | "kg";
    440440        }
    441441}
     
    451451Your weight on URANUS is 90.5 kg
    452452Your weight on NEPTUNE is 113.8 kg
     453Your weight on PLUTO is 6.3 kg
    453454\end{cfa}
    454455\caption{Planet Example}
  • doc/theses/jiada_liang_MMath/relatedwork.tex

    r089b39e1 r343c8be  
    2121Among theses languages, there are a large set of overlapping features, but each language has its own unique extensions and restrictions.
    2222
     23
    2324\section{Pascal}
    2425\label{s:Pascal}
    2526
    26 Classic Pascal introduced the \lstinline[language=Pascal]{const} aliasing declaration binding a name to a constant literal/expression.
     27Pascal introduced the \lstinline[language=Pascal]{const} aliasing declaration binding a name to a constant literal/expression.
    2728\begin{pascal}
    28 const one = 0 + 1;   Vowels = set of (A,E,I,O,U);   NULL = NIL;
    29                  PI = 3.14159;   Plus = '+';   Fred = 'Fred';
     29const Three = 2 + 1;   NULL = NIL;   PI = 3.14159;   Plus = '+';   Fred = 'Fred';
    3030\end{pascal}
    3131As stated, this mechanism is not an enumeration because there is no specific type (pseudo enumeration).
    32 Hence, there is no notion of a (possibly ordered) set, modulo the \lstinline[language=pascal]{set of} type.
     32Hence, there is no notion of a (possibly ordered) set.
    3333The type of each constant name (enumerator) is inferred from the constant-expression type.
    3434
    35 Free Pascal~\cite[\S~3.1.1]{FreePascal} is a modern, object-oriented version of classic Pascal, with a C-style enumeration type.
    36 Enumerators must be assigned in ascending numerical order with a constant expression and the range can be non-consecutive.
     35Pascal introduced the enumeration type characterized by a set of ordered, unscoped identifiers (enumerators), which are not overloadable.\footnote{%
     36Pascal is \emph{case-insensitive} so identifiers may appear in multiple forms and still be the same, \eg \lstinline{Mon}, \lstinline{moN}, and \lstinline{MON} (a questionable design decision).}
    3737\begin{pascal}
    38 Type EnumType = ( one, two, three, forty @= 40@, fortyone );
     38type Week = ( Mon, Tue, Wed, Thu, Fri, Sat, Sun );
    3939\end{pascal}
    40 Pseudo-functions @Pred@ and @Succ@ can only be used if the range is consecutive.
     40Object initialization and assignment are restricted to the enumerators of this type.
     41Enumerators are auto-initialized from left to right, starting at zero, incrementing by 1.
     42Enumerators \emph{cannot} be explicitly initialized.
     43Pascal provides a predefined type \lstinline[language=Pascal]{Boolean} defined as:
     44\begin{pascal}
     45type Boolean = ( false, true );
     46\end{pascal}
     47The enumeration ordering supports the relational operators @=@, @<>@, @<@, @<=@, @>=@, and @>@, provided both operands are the same (sub)type.
     48
     49The following auto-generated pseudo-functions exist for all enumeration types:
     50\begin{cquote}
     51\begin{tabular}{@{}ll@{}}
     52@succ( T )@     & @succ( Tue ) = Wed@ \\
     53@pred( T )@     & @pred( Tue ) =  Mon@ \\
     54@ord( T )@      & @ord( Tue ) = 1@
     55\end{tabular}
     56\end{cquote}
     57
     58Pascal provides \emph{consecutive} subtyping of an enumeration using subrange type.
     59\begin{pascal}
     60type Week = ( Mon, Tue, Wed, Thu, Fri, Sat, Sun );
     61                                Weekday = @Mon..Fri@;
     62                                Weekend = @Sat..Sun@;
     63var day : Week;
     64          wday : Weekday;
     65          wend : Weekend;
     66\end{pascal}
     67Hence, the ordering of the enumerators is crucial to provide the necessary ranges.
     68There is bidirectional assignment between the enumeration and its subranges.
     69\begin{pascal}
     70day := Sat;
     71@wday := day;@                  $\C[1.5in]{\{ check \}}$
     72wend := day;                    $\C{\{ maybe check \}}$
     73day := Mon;
     74wday := day;                    $\C{\{ maybe check \}}$
     75@wend := day;@                  $\C{\{ check \}}$
     76day := wday;                    $\C{\{ no check \}}$
     77day := wend;                    $\C{\{ no check \}}\CRT$
     78\end{pascal}
     79There should be a static/dynamic range check to verify values assigned to subtypes.
     80(Free Pascal does not check and aborts in certain situations, like writing an invalid enumerator.)
     81
     82An enumeration can be used in the @if@ and @case@ statements or iterating constructs.
     83\begin{cquote}
     84\setlength{\tabcolsep}{15pt}
     85\begin{tabular}{@{}ll@{}}
     86\begin{pascal}
     87if @day@ = wday then
     88        Writeln( day );
     89if @day@ <= Fri then
     90        Writeln( 'weekday');
     91
     92
     93\end{pascal}
     94&
     95\begin{pascal}
     96case @day@ of
     97  Mon..Fri :
     98        Writeln( 'weekday');
     99  Sat..Sun :
     100        Writeln( 'weekend')
     101end;
     102\end{pascal}
     103\end{tabular}
     104\end{cquote}
     105\begin{cquote}
     106\setlength{\tabcolsep}{15pt}
     107\begin{tabular}{@{}ll@{}}
     108\begin{pascal}
     109day := Mon;
     110while day <= Sat do begin
     111        Write( day, ' ' );
     112        day := succ( day );
     113end;
     114Mon Tue Wed Thu Fri Sat
     115\end{pascal}
     116&
     117\begin{pascal}
     118
     119for day := Mon to Sat do begin
     120        Write( day, ' ' );
     121
     122end;
     123Mon Tue Wed Thu Fri Sat
     124\end{pascal}
     125\end{tabular}
     126\end{cquote}
     127Note, subtype @Weekday@ and @Weekend@ cannot be used to define a case or loop range.
     128
     129An enumeration type can be used as an array dimension and subscript.
     130\begin{pascal}
     131Lunch : array( @Week@ ) of Time;
     132for day in Week loop
     133        Lunch( @day@ ) := ... ;       { set lunch time }
     134end loop;
     135\end{pascal}
     136
     137Free Pascal~\cite[\S~3.1.1]{FreePascal} is a modern, object-oriented version of Pascal, with a C-style enumeration type.
     138Enumerators can be assigned explicit values assigned in ascending numerical order using a constant expression, and the range can be non-consecutive.
     139\begin{pascal}
     140type Count = ( Zero, One, Two, Ten = 10, Eleven );
     141\end{pascal}
     142Pseudo-functions @pred@ and @succ@ can only be used if the range is consecutive.
     143Enumerating gives extraneous values.
     144\begin{pascal}
     145for cnt := Zero to Eleven do begin
     146        Write( ord( cnt ), ' ' );
     147end;
     1480 1 2 @3 4 5 6 7 8 9@ 10 11
     149\end{pascal}
     150
    41151The underlying type is an implementation-defined integral-type large enough to hold all enumerated values; it does not have to be the smallest possible type.
    42152The integral size can be explicitly specified using compiler directive @$PACKENUM@~$N$, where $N$ is the number of bytes, \eg:
     
    51161\section{Ada}
    52162
    53 An Ada enumeration type is a set of ordered unscoped identifiers (enumerators) bound to \emph{unique} \newterm{literals}.\footnote{%
     163An Ada enumeration type is a set of ordered, unscoped identifiers (enumerators) bound to \emph{unique} \newterm{literals}.\footnote{%
    54164Ada is \emph{case-insensitive} so identifiers may appear in multiple forms and still be the same, \eg \lstinline{Mon}, \lstinline{moN}, and \lstinline{MON} (a questionable design decision).}
    55165\begin{ada}
     
    770880(Note, after an @adt@'s type is know, the enumerator is inferred without qualification, \eg @.I(3)@.)
    771881
    772 An enumeration is created when \emph{all} the enumerators are unit-type.
     882An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration.
    773883\begin{swift}
    774884enum Week {
    775885        case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type
    776886};
    777 var week : Week = Week.Mon;
     887var week : Week = @Week.Mon@;
    778888\end{swift}
    779889As well, it is possible to type \emph{all} the enumerators with a common type, and set different values for each enumerator;
     
    10981208% https://dev.realworldocaml.org/runtime-memory-layout.html
    10991209
    1100 OCaml provides a variant (union) type, where multiple heterogeneously-typed objects share the same storage.
    1101 The simplest form of the variant type is a list of nullary datatype constructors, which is like an unscoped, opaque enumeration.
    1102 
    1103 OCaml provides a variant (union) type, which is an aggregation of heterogeneous types.
    1104 A basic variant is a list of nullary datatype constructors, which is like an unscoped, opaque enumeration.
     1210Like Haskell, OCaml @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration.
     1211When @enum@ is an ADT, pattern matching is used to discriminate among the variant types.
     1212\begin{cquote}
     1213\setlength{\tabcolsep}{20pt}
     1214\begin{tabular}{@{}l@{\hspace{35pt}}ll@{}}
     1215\begin{ocaml}
     1216type s = { i : int; j : int }
     1217let sv : s = { i = 3; j = 5 }
     1218@type@ adt =
     1219        I of int |    $\C[1in]{// int}$
     1220        F of float |  $\C{// float}$
     1221        S of s        $\C{// struct}\CRT$
     1222
     1223
     1224\end{ocaml}
     1225&
     1226\begin{ocaml}
     1227let adtprt( adtv : adt ) =
     1228        @match@ adtv with (* pattern matching *)
     1229                I i -> printf "%d\n" i |
     1230                F f -> printf "%g\n" f |
     1231                S sv -> printf "%d %d\n" sv.i sv.j
     1232let adtv : adt = I(3)       let _ = adtprt( adtv )
     1233let adtv : adt = F(3.5)   let _ = adtprt( adtv )
     1234let adtv : adt = S(sv)    let _ = adtprt( adtv )
     1235\end{ocaml}
     1236&
     1237\begin{ocaml}
     12383
     12393.5
     12403 5
     1241
     1242
     1243
     1244
     1245
     1246\end{ocaml}
     1247\end{tabular}
     1248\end{cquote}
     1249(Note, after an @adtv@'s type is know, the enumerator is inferred without qualification, \eg @I(3)@.)
     1250The type names are independent from the type value, and mapped to an opaque, ascending, integral tag, starting from 0, supporting relational operators @<@, @<=@, @>@, and @>=@.
     1251\begin{cquote}
     1252\setlength{\tabcolsep}{10pt}
     1253\begin{tabular}{@{}l@{\hspace{25pt}}ll@{}}
     1254\begin{ocaml}
     1255let silly( adtv : adt ) =
     1256        if adtv <= F(3.5) then
     1257                printf "<= F\n"
     1258        else if adtv >= S(sv) then
     1259                printf ">= S\n"
     1260\end{ocaml}
     1261&
     1262\begin{ocaml}
     1263let adtv : adt = I(3)       let _ = silly( adtv )
     1264let adtv : adt = F(3.5)   let _ = silly( adtv )
     1265let adtv : adt = S(sv)    let _ = silly( adtv )
     1266
     1267
     1268\end{ocaml}
     1269&
     1270\begin{ocaml}
     1271<= F
     1272<= F
     1273>= S
     1274
     1275
     1276\end{ocaml}
     1277\end{tabular}
     1278\end{cquote}
     1279In the example, type values must be specified (any appropriate values work) but ignored in the relational comparison of the type tag.
     1280
     1281An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration, where only the type tag is used.
    11051282\begin{ocaml}
    11061283type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun
    1107 let day : week @= Mon@                          $\C{(* bind *)}$
    1108 let take_class( d : week ) =
    1109         @match@ d with                                          $\C{(* matching *)}$
    1110                 Mon | Wed -> Printf.printf "CS442\n" |
    1111                 Tue | Thu -> Printf.printf "CS343\n" |
    1112                 Fri -> Printf.printf "Tutorial\n" |
    1113                 _ -> Printf.printf "Take a break\n"
    1114 let _ = take_class( Mon );
    1115 @CS442@
     1284let day : week = Mon
    11161285\end{ocaml}
    1117 The only operations are binding and pattern matching (equality), where the variant name is logically the implementation tag stored in the union for discriminating the value in the object storage.
    1118 After compilation, variant names are mapped to an opague ascending intergral type discriminants, starting from 0.
    1119 Here, function @take_class@ has a @week@ parameter, and returns @"CS442"@, if the week value is @Mon@ or @Wed@, @"CS343"@, if the value is @Tue@ or @Thu@, and @"Tutorial"@ for @Fri@.
    1120 The ``@_@'' is a wildcard matching any @week@ value, so the function returns @"Take a break"@ for values @Sat@ or @Sun@, which are not matched by the previous cases.
    1121 Since the variant has no type, it has a \newterm{0-arity constructor}, \ie no parameters.
    1122 Because @week@ is a union of values @Mon@ to @Sun@, it is a \newterm{union type} in turns of the functional-programming paradigm.
    1123 
    1124 Each variant can have an associated heterogeneous type, with an n-ary constructor for creating a corresponding value.
     1286Since the type names are opaque, a type-tag value cannot be explicitly set nor can it have a type other than integral.
     1287
     1288As seen, a type tag can be used in the @if@ and \lstinline[language=ocaml]{match} statements, where \lstinline[language=ocaml]{match} must be exhaustive or have a default case.
     1289
     1290Enumerating is accomplished by deriving from @enumerate@.
     1291
     1292Enumeration subtyping is allowed but inheritance is restricted to classes not types.
    11251293\begin{ocaml}
    1126 type colour = Red | Green of @string@ | Blue of @int * float@
     1294type weekday = Mon | Tue | Wed | Thu | Fri
     1295type weekend = Sat | Sun
     1296type week = Weekday of weekday | Weekend of weekend
     1297let day : week = Weekend Sun
    11271298\end{ocaml}
    1128 A variant with parameter is stored in a memory block, prefixed by an int tag and has its parameters stores as words in the block.
    1129 @colour@ is a summation of a nullary type, a unary product type of @string@, and a cross product of @int@ and @float@.
    1130 (Mathematically, a @Blue@ value is a Cartesian product of the types @int@ type and @float@.)
    1131 Hence, a variant type creates a sum of product of different types.
    1132 \begin{ocaml}
    1133 let c = Red                                                             $\C{(* 0-ary constructor, set tag *)}$
    1134 let _ = match c with Red -> Printf.printf "Red, "
    1135 let c = Green( "abc" )                                  $\C{(* 1-ary constructor, set tag *)}$
    1136 let _ = match c with Green g -> Printf.printf "%s, " g
    1137 let c = Blue( 1, 1.5 )                                  $\C{(* 2-ary constructor, set tag *)}$
    1138 let _ = match c with Blue( i, f ) -> Printf.printf "%d %g\n" i f
    1139 @Red, abc, 1 1.5@
    1140 \end{ocaml}
    1141 
    1142 A variant type can have a recursive definition.
    1143 \begin{ocaml}
    1144 type @stringList@ = Empty | Pair of string * @stringList@
    1145 \end{ocaml}
    1146 which is a recursive sum of product of types, called an \newterm{algebraic data-type}.
    1147 A recursive function is often used to pattern match against a recursive variant type.
    1148 \begin{ocaml}
    1149 let rec @len_of_string_list@( list : stringList ): int =
    1150         match list with
    1151                 Empty -> 0 |
    1152                 Pair( _ , r ) -> 1 + @len_of_string_list@ r
    1153 \end{ocaml}
    1154 Here, the head of the recursive type is removed and the remainder is processed until the type is empty.
    1155 Each recursion is counted to obtain the number of elements in the type.
    1156 
    1157 Note, the compiler statically guarantees that only the correct kind of type is used in the \lstinline[language=OCaml]{match} statement.
    1158 However, the union tag is dynamically set on binding (and possible reset on assignment), so a \lstinline[language=OCaml]{match} statement is effectively doing RTTI to select the matching case clause.
    1159 
    1160 In summary, an OCaml variant is a singleton value rather than a set of possibly ordered values, and hence, has no notion of enumerabilty.
    1161 Therefore it is not an enumeration, except for the simple opaque (nullary) case.
    11621299
    11631300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    12031340> I've marked 3 places with your name to shows places with enum ordering.
    12041341>
     1342> open Printf
    12051343> type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun
    12061344> let day : week = Mon
    12071345> let take_class( d : week ) =
    12081346>       if d <= Fri then                                (* Gregor *)
    1209 >               Printf.printf "week\n"
     1347>               printf "week\n"
    12101348>       else if d >= Sat then                   (* Gregor *)
    1211 >               Printf.printf "weekend\n";
     1349>               printf "weekend\n";
    12121350>       match d with
    1213 >               Mon | Wed -> Printf.printf "CS442\n" |
    1214 >               Tue | Thu -> Printf.printf "CS343\n" |
    1215 >               Fri -> Printf.printf "Tutorial\n" |
    1216 >               _ -> Printf.printf "Take a break\n"
     1351>               Mon | Wed -> printf "CS442\n" |
     1352>               Tue | Thu -> printf "CS343\n" |
     1353>               Fri -> printf "Tutorial\n" |
     1354>               _ -> printf "Take a break\n"
    12171355>
    12181356> let _ = take_class( Mon ); take_class( Sat );
     
    12201358> type colour = Red | Green of string | Blue of int * float
    12211359> let c = Red
    1222 > let _ = match c with Red -> Printf.printf "Red, "
     1360> let _ = match c with Red -> printf "Red, "
    12231361> let c = Green( "abc" )
    1224 > let _ = match c with Green g -> Printf.printf "%s, " g
     1362> let _ = match c with Green g -> printf "%s, " g
    12251363> let c = Blue( 1, 1.5 )
    1226 > let _ = match c with Blue( i, f ) -> Printf.printf "%d %g\n" i f
     1364> let _ = match c with Blue( i, f ) -> printf "%d %g\n" i f
    12271365>
    12281366> let check_colour(c: colour): string =
    12291367>       if c < Green( "xyz" ) then              (* Gregor *)
    1230 >               Printf.printf "green\n";
     1368>               printf "green\n";
    12311369>       match c with
    12321370>               Red -> "Red" |
     
    12421380>
    12431381> let _ = for i = 1 to 10 do
    1244 >       Printf.printf "%d, " i
     1382>       printf "%d, " i
    12451383> done
    12461384>
  • doc/theses/jiada_liang_MMath/test.ml

    r089b39e1 r343c8be  
    1 type s = { i :  int; }
    2 type fred = I of int | D of float | S of s
    3 type mary = I of int | D of int | S of int
    4 type weekday = Mon | Tue | Wed | Thu | Fri | Sat | Sun
    5 let day : weekday = Mon
    6 let take_class( d : weekday ) =
    7         if d <= Fri then                                (* Gregor *)
    8                 Printf.printf "weekday\n"
    9         else if d >= Sat then                   (* Gregor *)
    10                 Printf.printf "weekend\n";
     1open Printf
     2
     3type s = { i : int; j : int }
     4let sv : s = { i = 3; j = 5 }
     5type adt =
     6        I of int |
     7        F of float |
     8        S of s
     9let adtprt( adtv : adt ) =
     10        match adtv with (* pattern matching *)
     11                I i -> printf "%d\n" i |
     12                F f -> printf "%g\n" f |
     13                S sv -> printf "%d %d\n" sv.i sv.j
     14
     15let silly( adtv : adt ) =
     16        if adtv <= F(3.5) then
     17                printf "<= F\n"
     18        else if adtv >= S(sv) then
     19                printf ">= S\n"
     20
     21let adtv : adt = I(3) let _ = adtprt( adtv ); silly( adtv )
     22let adtv : adt = F(3.5) let _ = adtprt( adtv ); silly( adtv )
     23let adtv : adt = S(sv) let _ = adtprt( adtv ); silly( adtv )
     24
     25type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun [@@deriving enumerate]
     26let _ = List.iter ( fun e -> printf "%d" (to_val e) ) all_of_week
     27
     28let day : week = Mon
     29
     30let take_class( d : week ) =
     31        if d <= Fri then
     32                printf "weekday\n"
     33        else if d >= Sat then
     34                printf "weekend\n";
    1135        match d with
    12                 Mon | Wed -> Printf.printf "CS442\n" |
    13                 Tue | Thu -> Printf.printf "CS343\n" |
    14                 Fri -> Printf.printf "Tutorial\n" |
    15                 _ -> Printf.printf "Take a break\n"
     36                Mon | Wed -> printf "CS442\n" |
     37                Tue | Thu -> printf "CS343\n" |
     38                Fri -> printf "Tutorial\n" |
     39                _ -> printf "Take a break\n"
    1640
    1741let _ = take_class( Mon ); take_class( Sat );
    1842
    19 type colour = Red | Green of string | Blue of int * float
    20 let c = Red
    21 let _ = match c with Red -> Printf.printf "Red, "
    22 let c = Green( "abc" )
    23 let _ = match c with Green g -> Printf.printf "%s, " g
    24 let c = Blue( 1, 1.5 )
    25 let _ = match c with Blue( i, f ) -> Printf.printf "%d %g\n" i f
     43type weekday = Mon | Tue | Wed | Thu | Fri
     44type weekend = Sat | Sun of float
     45type week = Weekday of weekday | Weekend of weekend
     46let day : week = Weekend (Sun 3.5)
    2647
    27 let check_colour(c: colour): string =
    28         if c < Green( "xyz" ) then              (* Gregor *)
    29                 Printf.printf "green\n";
    30         match c with
    31                 Red -> "Red" |
    32                 Green g -> g |
    33                 Blue(i, f) -> string_of_int i ^ string_of_float f
    34 let _ = check_colour( Red ); check_colour( Green( "xyz" ) );
    35 
    36 type stringList = Empty | Pair of string * stringList
    37 let rec len_of_string_list(l: stringList): int =
    38         match l with
    39                 Empty -> 0 |
    40                 Pair(_ , r) -> 1 + len_of_string_list r
     48let take_class( d : week ) =
     49        if d <= Weekday Fri then
     50                printf "weekday\n"
     51        else if d >= Weekend Sat then
     52                printf "weekend\n";
     53        match d with
     54                Weekday Mon | Weekday Wed -> printf "CS442\n" |
     55                Weekday Tue | Weekday Thu -> printf "CS343\n" |
     56                Weekday Fri -> printf "Tutorial\n" |
     57                _ -> printf "Take a break\n"
     58let _ = take_class( day )
    4159
    4260let _ = for i = 1 to 10 do
    43         Printf.printf "%d, " i
     61        printf "%d, " i
    4462done
    4563
  • doc/theses/jiada_liang_MMath/test2.cfa

    r089b39e1 r343c8be  
    11#include <fstream.hfa>
    22#include <stdlib.hfa>
     3#include <enum.hfa>
    34
    45struct MR { double mass, radius; };
    56
    6 enum( MR ) Planet {
     7enum( MR ) Planet {                                                                             // typed enumeration
    78        //          mass (kg)  radius (km)
    89        MERCURY = { 0.330_E24, 2.4397_E6 },
    910        VENUS   = { 4.869_E24, 6.0518_E6 },
    1011        EARTH   = { 5.976_E24, 6.3781_E6 },
    11         MOON    = { 7.346_E22, 1.7380_E6 }, // not a planet
     12        MOON    = { 7.346_E22, 1.7380_E6 },                                     // not a planet
    1213        MARS    = { 0.642_E24, 3.3972_E6 },
    1314        JUPITER = { 1898._E24, 71.492_E6 },
     
    1516        URANUS  = { 86.86_E24, 25.559_E6 },
    1617        NEPTUNE = { 102.4_E24, 24.746_E6 },
     18        PLUTO   = { 1.303_E22, 1.1880_E6 },                                     // not a planet
    1719};
    1820
    19 enum( double ) { G = 6.6743_E-11 }; // universal gravitational constant (m3 kg-1 s-2)
     21enum( double ) { G = 6.6743_E-11 };                                             // universal gravitational constant (m3 kg-1 s-2)
    2022
    2123static double surfaceGravity( Planet p ) with( p ) {
    22         return G * mass / ( radius \ 2 ); // exponentiation
     24        return G * mass / ( radius \ 2 );                                       // no qualification, exponentiation
    2325}
    2426static double surfaceWeight( Planet p, double otherMass ) {
     
    2729
    2830int main( int argc, char * argv[] ) {
    29         if ( argc != 2 ) exit | "Usage: " | argv[0] | "earth-weight";
     31        if ( argc != 2 ) exit | "Usage: " | argv[0] | "earth-weight"; // terminate program
    3032
    3133        double earthWeight = convert( argv[1] );
    3234        double earthMass = earthWeight / surfaceGravity( EARTH );
    3335
    34         Planet p = fromInt( prng( SizeE(Planet) ) ); // select a random orbiting body
    35 //      Planet p = fromInt( prng( 9 ) ); // select a random orbiting body
    36         choose( p ) {
     36        Planet rp = fromInt( prng( countof( Planet ) ) );       // select random orbiting body
     37        choose( rp ) {                                                                          // implicit breaks
    3738          case MERCURY, VENUS, EARTH, MARS:
    38                 sout | labelE( p ) | "is a rocky planet";
     39                sout | label( rp ) | "is a rocky planet";
    3940          case JUPITER, SATURN, URANUS, NEPTUNE:
    40                 sout | labelE( p ) | "is a gas-giant planet";
     41                sout | label( rp ) | "is a gas-giant planet";
    4142          default:
    42                 sout | labelE( p ) | "is not a planet";
     43                sout | label( rp ) | "is not a planet";
    4344        }
    4445
    45 //      for ( Planet p = MERCURY; posE(p) <= posE(NEPTUNE); p = succ( p ) ) {
    46         for ( p; enum Planet ) {
    47                 sout | "Your weight on" | (p == MOON ? "the" : "") | labelE(p)
    48 //              sout | "Your weight on" | labelE(p)
    49                          | "is" | wd( 1,1, surfaceWeight( p, earthMass ) ) | "kg";
     46        for ( p; Planet ) {                                                                     // enumerate
     47                sout | "Your weight on" | ( p == MOON ? "the" : " " ) | label( p )
     48                         | "is" | wd( 1,1,  surfaceWeight( p, earthMass ) ) | "kg";
    5049        }
    5150}
Note: See TracChangeset for help on using the changeset viewer.