- Timestamp:
- Jun 25, 2024, 9:26:16 PM (7 months ago)
- 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. - Location:
- doc
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.sty
r089b39e1 r343c8be 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue May 28 07:56:52202414 %% Update Count : 65 813 %% Last Modified On : Mon Jun 24 08:03:28 2024 14 %% Update Count : 659 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 187 187 188 188 \newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.} 189 \newcommand{\eg}{\EG\ CheckCommaColon}189 \newcommand{\eg}{\EG\protect\CheckCommaColon} 190 190 191 191 \newcommand{\IE}{\abbrevFont{i}.\abbrevFont{e}.} 192 \newcommand{\ie}{\IE\ CheckCommaColon}192 \newcommand{\ie}{\IE\protect\CheckCommaColon} 193 193 194 194 \newcommand{\ETC}{\abbrevFont{etc}} 195 \newcommand{\etc}{\ETC\ CheckPeriod}195 \newcommand{\etc}{\ETC\protect\CheckPeriod} 196 196 197 197 \newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}} 198 \newcommand{\etal}{\ETAL\ CheckPeriod}198 \newcommand{\etal}{\ETAL\protect\CheckPeriod} 199 199 200 200 \newcommand{\VIZ}{\abbrevFont{viz}} 201 \newcommand{\viz}{\VIZ\ CheckPeriod}201 \newcommand{\viz}{\VIZ\protect\CheckPeriod} 202 202 203 203 \newcommand{\VS}{\abbrevFont{vs}} 204 \newcommand{\vs}{\VS\ CheckPeriod}204 \newcommand{\vs}{\VS\protect\CheckPeriod} 205 205 206 206 \newenvironment{cquote}{% -
doc/LaTeXmacros/common.tex
r089b39e1 r343c8be 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue May 28 07:41:21202414 %% Update Count : 66 513 %% Last Modified On : Mon Jun 24 08:01:50 2024 14 %% Update Count : 667 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 188 188 189 189 \newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.} 190 \newcommand{\eg}{\EG\ CheckCommaColon}190 \newcommand{\eg}{\EG\protect\CheckCommaColon} 191 191 192 192 \newcommand{\IE}{\abbrevFont{i}.\abbrevFont{e}.} 193 \newcommand{\ie}{\IE\ CheckCommaColon}193 \newcommand{\ie}{\IE\protect\CheckCommaColon} 194 194 195 195 \newcommand{\ETC}{\abbrevFont{etc}} 196 \newcommand{\etc}{\ETC\ CheckPeriod}196 \newcommand{\etc}{\ETC\protect\CheckPeriod} 197 197 198 198 \newcommand{\ETAL}{\abbrevFont{et}~\abbrevFont{al}} 199 \newcommand{\etal}{\ETAL\ CheckPeriod}199 \newcommand{\etal}{\ETAL\protect\CheckPeriod} 200 200 201 201 \newcommand{\VIZ}{\abbrevFont{viz}} 202 \newcommand{\viz}{\VIZ\ CheckPeriod}202 \newcommand{\viz}{\VIZ\protect\CheckPeriod} 203 203 204 204 \newcommand{\VS}{\abbrevFont{vs}} 205 \newcommand{\vs}{\VS\ CheckPeriod}205 \newcommand{\vs}{\VS\protect\CheckPeriod} 206 206 207 207 \newenvironment{cquote}{% -
doc/theses/jiada_liang_MMath/CFAenum.tex
r089b39e1 r343c8be 391 391 The unnamed enumeration provides the gravitational-constant enumerator @G@. 392 392 Function @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 @label E@ 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 .393 The 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@. 394 The resulting random orbital-body is used in a @choose@ statement. 395 The enumerators in the @case@ clause use enumerator position for testing. 396 The prints use @label@ to print an enumerator's name. 397 Finally, a loop enumerates 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 (@p == MOON@). 399 399 400 400 \begin{figure} … … 402 402 \begin{cfa} 403 403 struct MR { double mass, radius; }; 404 enum( @MR@ ) Planet { 404 enum( @MR@ ) Planet { $\C{// typed enumeration}$ 405 405 // mass (kg) radius (km) 406 406 MERCURY = { 0.330_E24, 2.4397_E6 }, 407 407 VENUS = { 4.869_E24, 6.0518_E6 }, 408 408 EARTH = { 5.976_E24, 6.3781_E6 }, 409 MOON = { 7.346_E22, 1.7380_E6 }, 409 MOON = { 7.346_E22, 1.7380_E6 }, $\C{// not a planet}$ 410 410 MARS = { 0.642_E24, 3.3972_E6 }, 411 411 JUPITER = { 1898._E24, 71.492_E6 }, … … 413 413 URANUS = { 86.86_E24, 25.559_E6 }, 414 414 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 }; 417 enum( double ) { G = 6.6743_E-11 }; $\C{// universal gravitational constant (m3 kg-1 s-2)}$ 417 418 static double surfaceGravity( Planet p ) @with( p )@ { 418 return G * mass / ( radius \ 2 ); $\C{//exponentiation}$419 return G * mass / ( radius @\@ 2 ); $\C{// no qualification, exponentiation}$ 419 420 } 420 421 static double surfaceWeight( Planet p, double otherMass ) { … … 422 423 } 423 424 int 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 425 426 double earthWeight = convert( argv[1] ); 426 427 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}$ 430 430 case MERCURY, VENUS, EARTH, MARS: 431 sout | @label E(p )@ | "is a rocky planet";432 @case JUPITER, SATURN, URANUS, NEPTUNE:@433 sout | label E(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"; 434 434 default: 435 sout | label E(p ) | "is not a planet";435 sout | label( rp ) | "is not a planet"; 436 436 } 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"; 440 440 } 441 441 } … … 451 451 Your weight on URANUS is 90.5 kg 452 452 Your weight on NEPTUNE is 113.8 kg 453 Your weight on PLUTO is 6.3 kg 453 454 \end{cfa} 454 455 \caption{Planet Example} -
doc/theses/jiada_liang_MMath/relatedwork.tex
r089b39e1 r343c8be 21 21 Among theses languages, there are a large set of overlapping features, but each language has its own unique extensions and restrictions. 22 22 23 23 24 \section{Pascal} 24 25 \label{s:Pascal} 25 26 26 ClassicPascal introduced the \lstinline[language=Pascal]{const} aliasing declaration binding a name to a constant literal/expression.27 Pascal introduced the \lstinline[language=Pascal]{const} aliasing declaration binding a name to a constant literal/expression. 27 28 \begin{pascal} 28 const one = 0 + 1; Vowels = set of (A,E,I,O,U); NULL = NIL; 29 PI = 3.14159; Plus = '+'; Fred = 'Fred'; 29 const Three = 2 + 1; NULL = NIL; PI = 3.14159; Plus = '+'; Fred = 'Fred'; 30 30 \end{pascal} 31 31 As 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.32 Hence, there is no notion of a (possibly ordered) set. 33 33 The type of each constant name (enumerator) is inferred from the constant-expression type. 34 34 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. 35 Pascal introduced the enumeration type characterized by a set of ordered, unscoped identifiers (enumerators), which are not overloadable.\footnote{% 36 Pascal 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).} 37 37 \begin{pascal} 38 Type EnumType = ( one, two, three, forty @= 40@, fortyone);38 type Week = ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); 39 39 \end{pascal} 40 Pseudo-functions @Pred@ and @Succ@ can only be used if the range is consecutive. 40 Object initialization and assignment are restricted to the enumerators of this type. 41 Enumerators are auto-initialized from left to right, starting at zero, incrementing by 1. 42 Enumerators \emph{cannot} be explicitly initialized. 43 Pascal provides a predefined type \lstinline[language=Pascal]{Boolean} defined as: 44 \begin{pascal} 45 type Boolean = ( false, true ); 46 \end{pascal} 47 The enumeration ordering supports the relational operators @=@, @<>@, @<@, @<=@, @>=@, and @>@, provided both operands are the same (sub)type. 48 49 The 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 58 Pascal provides \emph{consecutive} subtyping of an enumeration using subrange type. 59 \begin{pascal} 60 type Week = ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); 61 Weekday = @Mon..Fri@; 62 Weekend = @Sat..Sun@; 63 var day : Week; 64 wday : Weekday; 65 wend : Weekend; 66 \end{pascal} 67 Hence, the ordering of the enumerators is crucial to provide the necessary ranges. 68 There is bidirectional assignment between the enumeration and its subranges. 69 \begin{pascal} 70 day := Sat; 71 @wday := day;@ $\C[1.5in]{\{ check \}}$ 72 wend := day; $\C{\{ maybe check \}}$ 73 day := Mon; 74 wday := day; $\C{\{ maybe check \}}$ 75 @wend := day;@ $\C{\{ check \}}$ 76 day := wday; $\C{\{ no check \}}$ 77 day := wend; $\C{\{ no check \}}\CRT$ 78 \end{pascal} 79 There 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 82 An 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} 87 if @day@ = wday then 88 Writeln( day ); 89 if @day@ <= Fri then 90 Writeln( 'weekday'); 91 92 93 \end{pascal} 94 & 95 \begin{pascal} 96 case @day@ of 97 Mon..Fri : 98 Writeln( 'weekday'); 99 Sat..Sun : 100 Writeln( 'weekend') 101 end; 102 \end{pascal} 103 \end{tabular} 104 \end{cquote} 105 \begin{cquote} 106 \setlength{\tabcolsep}{15pt} 107 \begin{tabular}{@{}ll@{}} 108 \begin{pascal} 109 day := Mon; 110 while day <= Sat do begin 111 Write( day, ' ' ); 112 day := succ( day ); 113 end; 114 Mon Tue Wed Thu Fri Sat 115 \end{pascal} 116 & 117 \begin{pascal} 118 119 for day := Mon to Sat do begin 120 Write( day, ' ' ); 121 122 end; 123 Mon Tue Wed Thu Fri Sat 124 \end{pascal} 125 \end{tabular} 126 \end{cquote} 127 Note, subtype @Weekday@ and @Weekend@ cannot be used to define a case or loop range. 128 129 An enumeration type can be used as an array dimension and subscript. 130 \begin{pascal} 131 Lunch : array( @Week@ ) of Time; 132 for day in Week loop 133 Lunch( @day@ ) := ... ; { set lunch time } 134 end loop; 135 \end{pascal} 136 137 Free Pascal~\cite[\S~3.1.1]{FreePascal} is a modern, object-oriented version of Pascal, with a C-style enumeration type. 138 Enumerators can be assigned explicit values assigned in ascending numerical order using a constant expression, and the range can be non-consecutive. 139 \begin{pascal} 140 type Count = ( Zero, One, Two, Ten = 10, Eleven ); 141 \end{pascal} 142 Pseudo-functions @pred@ and @succ@ can only be used if the range is consecutive. 143 Enumerating gives extraneous values. 144 \begin{pascal} 145 for cnt := Zero to Eleven do begin 146 Write( ord( cnt ), ' ' ); 147 end; 148 0 1 2 @3 4 5 6 7 8 9@ 10 11 149 \end{pascal} 150 41 151 The 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. 42 152 The integral size can be explicitly specified using compiler directive @$PACKENUM@~$N$, where $N$ is the number of bytes, \eg: … … 51 161 \section{Ada} 52 162 53 An Ada enumeration type is a set of ordered unscoped identifiers (enumerators) bound to \emph{unique} \newterm{literals}.\footnote{%163 An Ada enumeration type is a set of ordered, unscoped identifiers (enumerators) bound to \emph{unique} \newterm{literals}.\footnote{% 54 164 Ada 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).} 55 165 \begin{ada} … … 770 880 (Note, after an @adt@'s type is know, the enumerator is inferred without qualification, \eg @.I(3)@.) 771 881 772 An enumeration is created when \emph{all} the enumerators are unit-type .882 An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration. 773 883 \begin{swift} 774 884 enum Week { 775 885 case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type 776 886 }; 777 var week : Week = Week.Mon;887 var week : Week = @Week.Mon@; 778 888 \end{swift} 779 889 As well, it is possible to type \emph{all} the enumerators with a common type, and set different values for each enumerator; … … 1098 1208 % https://dev.realworldocaml.org/runtime-memory-layout.html 1099 1209 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. 1210 Like Haskell, OCaml @enum@ provides two largely independent mechanisms from a single language feature: an ADT and an enumeration. 1211 When @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} 1216 type s = { i : int; j : int } 1217 let 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} 1227 let 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 1232 let adtv : adt = I(3) let _ = adtprt( adtv ) 1233 let adtv : adt = F(3.5) let _ = adtprt( adtv ) 1234 let adtv : adt = S(sv) let _ = adtprt( adtv ) 1235 \end{ocaml} 1236 & 1237 \begin{ocaml} 1238 3 1239 3.5 1240 3 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)@.) 1250 The 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} 1255 let 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} 1263 let adtv : adt = I(3) let _ = silly( adtv ) 1264 let adtv : adt = F(3.5) let _ = silly( adtv ) 1265 let 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} 1279 In the example, type values must be specified (any appropriate values work) but ignored in the relational comparison of the type tag. 1280 1281 An 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. 1105 1282 \begin{ocaml} 1106 1283 type 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@ 1284 let day : week = Mon 1116 1285 \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. 1286 Since the type names are opaque, a type-tag value cannot be explicitly set nor can it have a type other than integral. 1287 1288 As 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 1290 Enumerating is accomplished by deriving from @enumerate@. 1291 1292 Enumeration subtyping is allowed but inheritance is restricted to classes not types. 1125 1293 \begin{ocaml} 1126 type colour = Red | Green of @string@ | Blue of @int * float@ 1294 type weekday = Mon | Tue | Wed | Thu | Fri 1295 type weekend = Sat | Sun 1296 type week = Weekday of weekday | Weekend of weekend 1297 let day : week = Weekend Sun 1127 1298 \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, " g1137 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 f1139 @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 with1151 Empty -> 0 |1152 Pair( _ , r ) -> 1 + @len_of_string_list@ r1153 \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.1162 1299 1163 1300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 1203 1340 > I've marked 3 places with your name to shows places with enum ordering. 1204 1341 > 1342 > open Printf 1205 1343 > type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun 1206 1344 > let day : week = Mon 1207 1345 > let take_class( d : week ) = 1208 1346 > if d <= Fri then (* Gregor *) 1209 > Printf.printf "week\n"1347 > printf "week\n" 1210 1348 > else if d >= Sat then (* Gregor *) 1211 > Printf.printf "weekend\n";1349 > printf "weekend\n"; 1212 1350 > 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" 1217 1355 > 1218 1356 > let _ = take_class( Mon ); take_class( Sat ); … … 1220 1358 > type colour = Red | Green of string | Blue of int * float 1221 1359 > let c = Red 1222 > let _ = match c with Red -> Printf.printf "Red, "1360 > let _ = match c with Red -> printf "Red, " 1223 1361 > let c = Green( "abc" ) 1224 > let _ = match c with Green g -> Printf.printf "%s, " g1362 > let _ = match c with Green g -> printf "%s, " g 1225 1363 > let c = Blue( 1, 1.5 ) 1226 > let _ = match c with Blue( i, f ) -> Printf.printf "%d %g\n" i f1364 > let _ = match c with Blue( i, f ) -> printf "%d %g\n" i f 1227 1365 > 1228 1366 > let check_colour(c: colour): string = 1229 1367 > if c < Green( "xyz" ) then (* Gregor *) 1230 > Printf.printf "green\n";1368 > printf "green\n"; 1231 1369 > match c with 1232 1370 > Red -> "Red" | … … 1242 1380 > 1243 1381 > let _ = for i = 1 to 10 do 1244 > Printf.printf "%d, " i1382 > printf "%d, " i 1245 1383 > done 1246 1384 > -
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"; 1 open Printf 2 3 type s = { i : int; j : int } 4 let sv : s = { i = 3; j = 5 } 5 type adt = 6 I of int | 7 F of float | 8 S of s 9 let 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 15 let 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 21 let adtv : adt = I(3) let _ = adtprt( adtv ); silly( adtv ) 22 let adtv : adt = F(3.5) let _ = adtprt( adtv ); silly( adtv ) 23 let adtv : adt = S(sv) let _ = adtprt( adtv ); silly( adtv ) 24 25 type week = Mon | Tue | Wed | Thu | Fri | Sat | Sun [@@deriving enumerate] 26 let _ = List.iter ( fun e -> printf "%d" (to_val e) ) all_of_week 27 28 let day : week = Mon 29 30 let take_class( d : week ) = 31 if d <= Fri then 32 printf "weekday\n" 33 else if d >= Sat then 34 printf "weekend\n"; 11 35 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" 16 40 17 41 let _ = take_class( Mon ); take_class( Sat ); 18 42 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 43 type weekday = Mon | Tue | Wed | Thu | Fri 44 type weekend = Sat | Sun of float 45 type week = Weekday of weekday | Weekend of weekend 46 let day : week = Weekend (Sun 3.5) 26 47 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 48 let 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" 58 let _ = take_class( day ) 41 59 42 60 let _ = for i = 1 to 10 do 43 Printf.printf "%d, " i61 printf "%d, " i 44 62 done 45 63 -
doc/theses/jiada_liang_MMath/test2.cfa
r089b39e1 r343c8be 1 1 #include <fstream.hfa> 2 2 #include <stdlib.hfa> 3 #include <enum.hfa> 3 4 4 5 struct MR { double mass, radius; }; 5 6 6 enum( MR ) Planet { 7 enum( MR ) Planet { // typed enumeration 7 8 // mass (kg) radius (km) 8 9 MERCURY = { 0.330_E24, 2.4397_E6 }, 9 10 VENUS = { 4.869_E24, 6.0518_E6 }, 10 11 EARTH = { 5.976_E24, 6.3781_E6 }, 11 MOON = { 7.346_E22, 1.7380_E6 }, 12 MOON = { 7.346_E22, 1.7380_E6 }, // not a planet 12 13 MARS = { 0.642_E24, 3.3972_E6 }, 13 14 JUPITER = { 1898._E24, 71.492_E6 }, … … 15 16 URANUS = { 86.86_E24, 25.559_E6 }, 16 17 NEPTUNE = { 102.4_E24, 24.746_E6 }, 18 PLUTO = { 1.303_E22, 1.1880_E6 }, // not a planet 17 19 }; 18 20 19 enum( double ) { G = 6.6743_E-11 }; 21 enum( double ) { G = 6.6743_E-11 }; // universal gravitational constant (m3 kg-1 s-2) 20 22 21 23 static double surfaceGravity( Planet p ) with( p ) { 22 return G * mass / ( radius \ 2 ); //exponentiation24 return G * mass / ( radius \ 2 ); // no qualification, exponentiation 23 25 } 24 26 static double surfaceWeight( Planet p, double otherMass ) { … … 27 29 28 30 int 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 30 32 31 33 double earthWeight = convert( argv[1] ); 32 34 double earthMass = earthWeight / surfaceGravity( EARTH ); 33 35 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 37 38 case MERCURY, VENUS, EARTH, MARS: 38 sout | label E(p ) | "is a rocky planet";39 sout | label( rp ) | "is a rocky planet"; 39 40 case JUPITER, SATURN, URANUS, NEPTUNE: 40 sout | label E(p ) | "is a gas-giant planet";41 sout | label( rp ) | "is a gas-giant planet"; 41 42 default: 42 sout | label E(p ) | "is not a planet";43 sout | label( rp ) | "is not a planet"; 43 44 } 44 45 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"; 50 49 } 51 50 }
Note: See TracChangeset
for help on using the changeset viewer.