source: doc/theses/jiada_liang_MMath/relatedwork.tex @ 956299b

Last change on this file since 956299b was 956299b, checked in by Peter A. Buhr <pabuhr@…>, 4 months ago

copy enum proposal to enum thesis

  • Property mode set to 100644
File size: 30.6 KB
Line 
1\chapter{Related Work}
2\label{s:RelatedWork}
3
4Enumerations exist in many popular programming languages, e.g., Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp, \CC, Go~\cite{Go}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}, and the algebraic data-type in functional programming.
5There are a large set of overlapping features among these languages, but each language has its own unique restrictions and extensions.
6
7\section{(Free) Pascal}
8
9Free Pascal is a modern object-oriented version of the classic Pascal programming language.
10It allows a C-style enumeration type, where enumerators must be in assigned in ascending numerical order with a constant expression and the range can be non-consecutive.
11\begin{lstlisting}[language=pascal,{moredelim=**[is][\color{red}]{@}{@}}]
12Type EnumType = ( one, two, three, forty @= 40@, fortyone );
13\end{lstlisting}
14Pseudo-functions @Pred@ and @Succ@ can only be used if the range is consecutive.
15The 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.
16The size underlying integral type can be explicitly specified using compiler directive @$PACKENUM@~$N$, where $N$ is the number of bytes, e.g.:
17\begin{lstlisting}[language=pascal,{moredelim=**[is][\color{red}]{@}{@}}]
18Type @{$\color{red}\$$PACKENUM 1}@ SmallEnum = ( one, two, three );
19            @{$\color{red}\$$PACKENUM 4}@ LargeEnum = ( BigOne, BigTwo, BigThree );
20Var S : SmallEnum; { 1 byte }
21          L : LargeEnum; { 4 bytes}
22\end{lstlisting}
23
24
25\section{Ada}
26
27An enumeration type is defined as a list of possible values:
28\begin{lstlisting}[language=ada]
29type RGB is (Red, Green, Blue);
30\end{lstlisting}
31Like for numeric types, where e.g., 1 is an integer literal, @Red@, @Green@ and @Blue@ are called the literals of this type.
32There are no other values assignable to objects of this type.
33
34\paragraph{Operators and attributes} ~\newline
35Apart from equality (@"="@), the only operators on enumeration types are the ordering operators: @"<"@, @"<="@, @"="@, @"/="@, @">="@, @">"@, where the order relation is given implicitly by the sequence of literals:
36Each literal has a position, starting with 0 for the first, incremented by one for each successor.
37This position can be queried via the @'Pos@ attribute; the inverse is @'Val@, which returns the corresponding literal. In our example:
38\begin{lstlisting}[language=ada]
39RGB'Pos (Red) = 0
40RGB'Val (0)   = Red
41\end{lstlisting}
42There are two other important attributes: @Image@ and @Value@.
43@Image@ returns the string representation of the value (in capital letters), @Value@ is the inverse:
44\begin{lstlisting}[language=ada]
45RGB'Image ( Red ) = "RED"
46RGB'Value ("Red") =  Red
47\end{lstlisting}
48These attributes are important for simple IO (there are more elaborate IO facilities in @Ada.Text_IO@ for enumeration types).
49Note that, since Ada is case-insensitive, the string given to @'Value@ can be in any case.
50
51\paragraph{Enumeration literals} ~\newline
52Literals are overloadable, i.e. you can have another type with the same literals.
53\begin{lstlisting}[language=ada]
54type Traffic_Light is (Red, Yellow, Green);
55\end{lstlisting}
56Overload resolution within the context of use of a literal normally resolves which @Red@ is meant.
57Only if you have an unresolvable overloading conflict, you can qualify with special syntax which @Red@ is meant:
58\begin{lstlisting}[language=ada]
59RGB'(Red)
60\end{lstlisting}
61Like many other declarative items, enumeration literals can be renamed.
62In fact, such a literal is actually a function, so it has to be renamed as such:
63\begin{lstlisting}[language=ada]
64function Red return P.RGB renames P.Red;
65\end{lstlisting}
66Here, @RGB@ is assumed to be defined in package @P@, which is visible at the place of the renaming declaration.
67Renaming makes @Red@ directly visible without necessity to resort the use-clause.
68
69Note that redeclaration as a function does not affect the staticness of the literal.
70
71\paragraph{Characters as enumeration literals} ~\newline
72Rather unique to Ada is the use of character literals as enumeration literals:
73\begin{lstlisting}[language=ada]
74type ABC is ('A', 'B', 'C');
75\end{lstlisting}
76This literal @'A'@ has nothing in common with the literal @'A'@ of the predefined type @Character@ (or @Wide_Character@).
77
78Every type that has at least one character literal is a character type.
79For every character type, string literals and the concatenation operator @"&"@ are also implicitly defined.
80\begin{lstlisting}[language=ada]
81type My_Character is (No_Character, 'a', Literal, 'z');
82type My_String is array (Positive range <>) of My_Character;
83
84S: My_String := "aa" & Literal & "za" & 'z';
85T: My_String := ('a', 'a', Literal, 'z', 'a', 'z');
86\end{lstlisting}
87In this example, @S@ and @T@ have the same value.
88
89Ada's @Character@ type is defined that way.
90See Ada Programming/Libraries/Standard.
91
92\paragraph{Booleans as enumeration literals} ~\newline
93Also Booleans are defined as enumeration types:
94\begin{lstlisting}[language=ada]
95type Boolean is (False, True);
96\end{lstlisting}
97There is special semantics implied with this declaration in that objects and expressions of this type can be used as conditions.
98Note that the literals @False@ and @True@ are not Ada keywords.
99
100Thus it is not sufficient to declare a type with these literals and then hope objects of this type can be used like so:
101\begin{lstlisting}[language=ada]
102type My_Boolean is (False, True);
103Condition: My_Boolean;
104
105if Condition then -- wrong, won't compile
106\end{lstlisting}
107
108If you need your own Booleans (perhaps with special size requirements), you have to derive from the predefined Boolean:
109\begin{lstlisting}[language=ada]
110type My_Boolean is new Boolean;
111Condition: My_Boolean;
112
113if Condition then -- OK
114\end{lstlisting}
115
116\paragraph{Enumeration subtypes} ~\newline
117You can use range to subtype an enumeration type:
118\begin{lstlisting}[language=ada]
119subtype Capital_Letter is Character range 'A' .. 'Z';
120type Day_Of_Week is (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
121subtype Working_Day is Day_Of_Week range Monday .. Friday;
122\end{lstlisting}
123
124\paragraph{Using enumerations} ~\newline
125Enumeration types being scalar subtypes, type attributes such as @First@ and @Succ@ will allow stepping through a subsequence of the values.
126\begin{lstlisting}[language=ada]
127case Day_Of_Week'First is
128        when Sunday =>
129           ISO (False);
130        when Day_Of_Week'Succ(Sunday) =>
131           ISO (True);
132        when Tuesday .. Saturday =>
133           raise Program_Error;
134end case;
135\end{lstlisting}
136A loop will automatically step through the values of the subtype's range.
137Filtering week days to include only working days with an even position number:
138\begin{lstlisting}[language=ada]
139        for Day in Working_Day loop
140                if Day_Of_Week'Pos(Day) mod 2 = 0 then
141                        Work_In_Backyard;
142                end if;
143        end loop;
144\end{lstlisting}
145Enumeration types can be used as array index subtypes, yielding a table feature:
146\begin{lstlisting}[language=ada]
147type Officer_ID is range 0 .. 50;
148type Schedule is array (Working_Day) of Officer_ID;
149\end{lstlisting}
150
151\begin{lstlisting}[language=ada]
152type Subtype_Name is (Id1, Id2, Id3 ... );
153\end{lstlisting}
154where @Id1@, @Id2@, etc. are identifiers or characters literals.
155In either case, the legal values of the type are referred to as "enumeration literals."
156Each of these values has a "position number" corresponding to its position in the list such that @Id1@ has position 0, @Id2@ has position 1, and the Nth value has position N-1.
157
158\paragraph{Attributes of Enumeration Types} ~\newline
159An enumeration type, @T@, has the following attributes: @T'First@, @T'Last@, @T'Range@, @T'Pred@, @T'Succ@, @T'Min@, @T'Max@, @T'Image@, @T'Wide_Image@, @T'Value@, @T'Wide_Value@, @T'Pos@, and @T'Val@ (pronounced "T tick first", "T tick last", etc.).
160Most of these are illustrated in the example program given below, and most of them produce what you would intuitively expect based on their names.
161
162@T'Image@ and @T'Value@ form a complementary pair of attributes.
163The former takes a value in @T@ and returns a String representation of that value.
164The latter takes a @String@ that is a representation of a value in @T@ and returns that value.
165
166@T'Pos@ and @T'Val@ form another complementary pair.
167The former takes a value in @T@ and returns its position number.
168The latter takes a position number and returns the corresponding value of type @T@.
169
170
171\section{C\raisebox{-0.7ex}{\LARGE$^\sharp$}\xspace} % latex bug: cannot use \relsize{2} so use \LARGE
172
173\lstdefinelanguage{swift}
174{
175  morekeywords={
176    open,catch,@escaping,nil,throws,func,if,then,else,for,in,while,do,switch,case,default,where,break,continue,fallthrough,return,
177    typealias,struct,class,enum,protocol,var,func,let,get,set,willSet,didSet,inout,init,deinit,extension,
178    subscript,prefix,operator,infix,postfix,precedence,associativity,left,right,none,convenience,dynamic,
179    final,lazy,mutating,nonmutating,optional,override,required,static,unowned,safe,weak,internal,
180    private,public,is,as,self,unsafe,dynamicType,true,false,nil,Type,Protocol,
181  },
182  morecomment=[l]{//}, % l is for line comment
183  morecomment=[s]{/*}{*/}, % s is for start and end delimiter
184  morestring=[b]", % defines that strings are enclosed in double quotes
185  breaklines=true,
186  escapeinside={\%*}{*)},
187%  numbers=left,
188  captionpos=b,
189  breakatwhitespace=true,
190  basicstyle=\linespread{0.9}\sf, % https://tex.stackexchange.com/a/102728/129441
191}
192
193Model custom types that define a list of possible values.
194
195An enumeration defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.
196
197If you are familiar with C, you will know that C enumerations assign related names to a set of integer values.
198Enumerations in Swift are much more flexible, and don't have to provide a value for each case of the enumeration.
199If a value (known as a raw value) is provided for each enumeration case, the value can be a string, a character, or a value of any integer or floating-point type.
200
201Alternatively, enumeration cases can specify associated values of any type to be stored along with each different case value, much as unions or variants do in other languages.
202You can define a common set of related cases as part of one enumeration, each of which has a different set of values of appropriate types associated with it.
203
204Enumerations in Swift are first-class types in their own right.
205They adopt many features traditionally supported only by classes, such as computed properties to provide additional information about the enumeration's current value, and instance methods to provide functionality related to the values the enumeration represents.
206Enumerations can also define initializers to provide an initial case value;
207can be extended to expand their functionality beyond their original implementation; and can conform to protocols to provide standard functionality.
208
209For more about these capabilities, see Properties, Methods, Initialization, Extensions, and Protocols.
210
211\paragraph{Enumeration Syntax}
212
213You introduce enumerations with the @enum@ keyword and place their entire definition within a pair of braces:
214\begin{lstlisting}[language=swift]
215enum SomeEnumeration {
216    // enumeration definition goes here
217}
218\end{lstlisting}
219Here's an example for the four main points of a compass:
220\begin{lstlisting}[language=swift]
221enum CompassPoint {
222    case north
223    case south
224    case east
225    case west
226}
227\end{lstlisting}
228The values defined in an enumeration (such as @north@, @south@, @east@, and @west@) are its enumeration cases.
229You use the @case@ keyword to introduce new enumeration cases.
230
231Note:
232Swift enumeration cases don't have an integer value set by default, unlike languages like C and Objective-C.
233In the CompassPoint example above, @north@, @south@, @east@ and @west@ don't implicitly equal 0, 1, 2 and 3.
234Instead, the different enumeration cases are values in their own right, with an explicitly defined type of CompassPoint.
235
236Multiple cases can appear on a single line, separated by commas:
237\begin{lstlisting}[language=swift]
238enum Planet {
239    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
240}
241\end{lstlisting}
242Each enumeration definition defines a new type.
243Like other types in Swift, their names (such as @CompassPoint@ and @Planet@) start with a capital letter.
244Give enumeration types singular rather than plural names, so that they read as self-evident:
245\begin{lstlisting}[language=swift]
246var directionToHead = CompassPoint.west
247\end{lstlisting}
248The type of @directionToHead@ is inferred when it's initialized with one of the possible values of @CompassPoint@.
249Once @directionToHead@ is declared as a @CompassPoint@, you can set it to a different @CompassPoint@ value using a shorter dot syntax:
250\begin{lstlisting}[language=swift]
251directionToHead = .east
252\end{lstlisting}
253The type of @directionToHead@ is already known, and so you can drop the type when setting its value.
254This makes for highly readable code when working with explicitly typed enumeration values.
255
256\paragraph{Matching Enumeration Values with a Switch Statement}
257
258You can match individual enumeration values with a switch statement:
259\begin{lstlisting}[language=swift]
260directionToHead = .south
261switch directionToHead {
262case .north:
263    print("Lots of planets have a north")
264case .south:
265    print("Watch out for penguins")
266case .east:
267    print("Where the sun rises")
268case .west:
269    print("Where the skies are blue")
270}
271// Prints "Watch out for penguins"
272\end{lstlisting}
273You can read this code as:
274\begin{quote}
275"Consider the value of directionToHead.
276In the case where it equals @.north@, print "Lots of planets have a north".
277In the case where it equals @.south@, print "Watch out for penguins"."
278
279...and so on.
280\end{quote}
281As described in Control Flow, a switch statement must be exhaustive when considering an enumeration's cases.
282If the case for @.west@ is omitted, this code doesn't compile, because it doesn't consider the complete list of @CompassPoint@ cases.
283Requiring exhaustiveness ensures that enumeration cases aren't accidentally omitted.
284
285When it isn't appropriate to provide a case for every enumeration case, you can provide a default case to cover any cases that aren't addressed explicitly:
286\begin{lstlisting}[language=swift]
287let somePlanet = Planet.earth
288switch somePlanet {
289case .earth:
290    print("Mostly harmless")
291default:
292    print("Not a safe place for humans")
293}
294// Prints "Mostly harmless"
295\end{lstlisting}
296
297\paragraph{Iterating over Enumeration Cases}
298
299For some enumerations, it's useful to have a collection of all of that enumeration's cases.
300You enable this by writing @CaseIterable@ after the enumeration's name.
301Swift exposes a collection of all the cases as an allCases property of the enumeration type.
302Here's an example:
303\begin{lstlisting}[language=swift]
304enum Beverage: CaseIterable {
305    case coffee, tea, juice
306}
307let numberOfChoices = Beverage.allCases.count
308print("\(numberOfChoices) beverages available")
309// Prints "3 beverages available"
310\end{lstlisting}
311In the example above, you write @Beverage.allCases@ to access a collection that contains all of the cases of the @Beverage@ enumeration.
312You can use @allCases@ like any other collection -- the collection's elements are instances of the enumeration type, so in this case they're Beverage values.
313The example above counts how many cases there are, and the example below uses a for-in loop to iterate over all the cases.
314\begin{lstlisting}[language=swift]
315for beverage in Beverage.allCases {
316    print(beverage)
317}
318// coffee
319// tea
320// juice
321\end{lstlisting}
322The syntax used in the examples above marks the enumeration as conforming to the @CaseIterable@ protocol.
323For information about protocols, see Protocols.
324
325\paragraph{Associated Values}
326The examples in the previous section show how the cases of an enumeration are a defined (and typed) value in their own right.
327You can set a constant or variable to Planet.earth, and check for this value later.
328However, it's sometimes useful to be able to store values of other types alongside these case values.
329This additional information is called an associated value, and it varies each time you use that case as a value in your code.
330
331You can define Swift enumerations to store associated values of any given type, and the value types can be different for each case of the enumeration if needed.
332Enumerations similar to these are known as discriminated unions, tagged unions, or variants in other programming languages.
333
334For example, suppose an inventory tracking system needs to track products by two different types of barcode.
335Some products are labeled with 1D barcodes in UPC format, which uses the numbers 0 to 9.
336Each barcode has a number system digit, followed by five manufacturer code digits and five product code digits.
337These are followed by a check digit to verify that the code has been scanned correctly:
338
339Other products are labeled with 2D barcodes in QR code format, which can use any ISO 8859-1 character and can encode a string up to 2,953 characters long:
340
341It's convenient for an inventory tracking system to store UPC barcodes as a tuple of four integers, and QR code barcodes as a string of any length.
342
343In Swift, an enumeration to define product barcodes of either type might look like this:
344\begin{lstlisting}[language=swift]
345enum Barcode {
346    case upc(Int, Int, Int, Int)
347    case qrCode(String)
348}
349\end{lstlisting}
350This can be read as:
351\begin{quote}
352"Define an enumeration type called Barcode, which can take either a value of upc with an associated value of type @(Int, Int, Int, Int)@, or a value of @qrCode@ with an associated value of type @String@."
353\end{quote}
354This definition doesn't provide any actual @Int@ or @String@ values -- it just defines the type of associated values that Barcode constants and variables can store when they're equal to @Barcode.upc@ or @Barcode.qrCode@.
355
356You can then create new barcodes using either type:
357\begin{lstlisting}[language=swift]
358var productBarcode = Barcode.upc(8, 85909, 51226, 3)
359\end{lstlisting}
360This example creates a new variable called @productBarcode@ and assigns it a value of @Barcode.upc@ with an associated tuple value of @(8, 85909, 51226, 3)@.
361
362You can assign the same product a different type of barcode:
363\begin{lstlisting}[language=swift]
364productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
365\end{lstlisting}
366At this point, the original @Barcode.upc@ and its integer values are replaced by the new @Barcode.qrCode@ and its string value.
367Constants and variables of type Barcode can store either a @.upc@ or a @.qrCode@ (together with their associated values), but they can store only one of them at any given time.
368
369You can check the different barcode types using a switch statement, similar to the example in Matching Enumeration Values with a Switch Statement.
370This time, however, the associated values are extracted as part of the switch statement.
371You extract each associated value as a constant (with the let prefix) or a variable (with the var prefix) for use within the switch case's body:
372\begin{lstlisting}[language=swift][language=swift]
373switch productBarcode {
374case .upc(let numberSystem, let manufacturer, let product, let check):
375    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
376case .qrCode(let productCode):
377    print("QR code: \(productCode).")
378}
379// Prints "QR code: ABCDEFGHIJKLMNOP."
380\end{lstlisting}
381If all of the associated values for an enumeration case are extracted as constants, or if all are extracted as variables, you can place a single let or var annotation before the case name, for brevity:
382\begin{lstlisting}[language=swift]
383switch productBarcode {
384case let .upc(numberSystem, manufacturer, product, check):
385    print("UPC : \(numberSystem), \(manufacturer), \(product), \(check).")
386case let .qrCode(productCode):
387    print("QR code: \(productCode).")
388}
389// Prints "QR code: ABCDEFGHIJKLMNOP."
390\end{lstlisting}
391
392\paragraph{Raw Values}
393
394The barcode example in Associated Values shows how cases of an enumeration can declare that they store associated values of different types.
395As an alternative to associated values, enumeration cases can come prepopulated with default values (called raw values), which are all of the same type.
396
397Here's an example that stores raw ASCII values alongside named enumeration cases:
398\begin{lstlisting}[language=swift]
399enum ASCIIControlCharacter: Character {
400    case tab = "\t"
401    case lineFeed = "\n"
402    case carriageReturn = "\r"
403}
404\end{lstlisting}
405Here, the raw values for an enumeration called ASCIIControlCharacter are defined to be of type Character, and are set to some of the more common ASCII control characters.
406Character values are described in Strings and Characters.
407
408Raw values can be strings, characters, or any of the integer or floating-point number types.
409Each raw value must be unique within its enumeration declaration.
410
411Note
412
413Raw values are not the same as associated values.
414Raw values are set to prepopulated values when you first define the enumeration in your code, like the three ASCII codes above.
415The raw value for a particular enumeration case is always the same.
416Associated values are set when you create a new constant or variable based on one of the enumeration's cases, and can be different each time you do so.
417Implicitly Assigned Raw Values
418
419When you're working with enumerations that store integer or string raw values, you don't have to explicitly assign a raw value for each case.
420When you don't, Swift automatically assigns the values for you.
421
422For example, when integers are used for raw values, the implicit value for each case is one more than the previous case.
423If the first case doesn't have a value set, its value is 0.
424
425The enumeration below is a refinement of the earlier Planet enumeration, with integer raw values to represent each planet's order from the sun:
426
427\begin{lstlisting}[language=swift]
428enum Planet: Int {
429    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
430}
431\end{lstlisting}
432In the example above, Planet.mercury has an explicit raw value of 1, Planet.venus has an implicit raw value of 2, and so on.
433
434When strings are used for raw values, the implicit value for each case is the text of that case's name.
435
436The enumeration below is a refinement of the earlier CompassPoint enumeration, with string raw values to represent each direction's name:
437\begin{lstlisting}[language=swift]
438enum CompassPoint: String {
439    case north, south, east, west
440}
441\end{lstlisting}
442In the example above, CompassPoint.south has an implicit raw value of "south", and so on.
443
444You access the raw value of an enumeration case with its rawValue property:
445\begin{lstlisting}[language=swift]
446let earthsOrder = Planet.earth.rawValue
447// earthsOrder is 3
448
449let sunsetDirection = CompassPoint.west.rawValue
450// sunsetDirection is "west"
451\end{lstlisting}
452
453\paragraph{Initializing from a Raw Value}
454
455If you define an enumeration with a raw-value type, the enumeration automatically receives an initializer that takes a value of the raw value's type (as a parameter called rawValue) and returns either an enumeration case or nil.
456You can use this initializer to try to create a new instance of the enumeration.
457
458This example identifies Uranus from its raw value of 7:
459\begin{lstlisting}[language=swift]
460let possiblePlanet = Planet(rawValue: 7)
461// possiblePlanet is of type Planet? and equals Planet.uranus
462\end{lstlisting}
463Not all possible Int values will find a matching planet, however.
464Because of this, the raw value initializer always returns an optional enumeration case.
465In the example above, possiblePlanet is of type Planet?, or "optional Planet."
466Note
467
468The raw value initializer is a failable initializer, because not every raw value will return an enumeration case.
469For more information, see Failable Initializers.
470
471If you try to find a planet with a position of 11, the optional Planet value returned by the raw value initializer will be nil:
472\begin{lstlisting}[language=swift]
473let positionToFind = 11
474if let somePlanet = Planet(rawValue: positionToFind) {
475    switch somePlanet {
476    case .earth:
477        print("Mostly harmless")
478    default:
479        print("Not a safe place for humans")
480    }
481} else {
482    print("There isn't a planet at position \(positionToFind)")
483}
484// Prints "There isn't a planet at position 11"
485\end{lstlisting}
486This example uses optional binding to try to access a planet with a raw value of 11.
487The statement if let somePlanet = Planet(rawValue: 11) creates an optional Planet, and sets somePlanet to the value of that optional Planet if it can be retrieved.
488In this case, it isn't possible to retrieve a planet with a position of 11, and so the else branch is executed instead.
489
490\paragraph{Recursive Enumerations}
491
492A recursive enumeration is an enumeration that has another instance of the enumeration as the associated value for one or more of the enumeration cases.
493You indicate that an enumeration case is recursive by writing indirect before it, which tells the compiler to insert the necessary layer of indirection.
494
495For example, here is an enumeration that stores simple arithmetic expressions:
496\begin{lstlisting}[language=swift]
497enum ArithmeticExpression {
498    case number(Int)
499    indirect case addition(ArithmeticExpression, ArithmeticExpression)
500    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
501}
502\end{lstlisting}
503You can also write indirect before the beginning of the enumeration to enable indirection for all of the enumeration's cases that have an associated value:
504\begin{lstlisting}[language=swift]
505indirect enum ArithmeticExpression {
506    case number(Int)
507    case addition(ArithmeticExpression, ArithmeticExpression)
508    case multiplication(ArithmeticExpression, ArithmeticExpression)
509}
510\end{lstlisting}
511This enumeration can store three kinds of arithmetic expressions: a plain number, the addition of two expressions, and the multiplication of two expressions.
512The addition and multiplication cases have associated values that are also arithmetic expressions -- these associated values make it possible to nest expressions.
513For example, the expression (5 + 4) * 2 has a number on the right-hand side of the multiplication and another expression on the left-hand side of the multiplication.
514Because the data is nested, the enumeration used to store the data also needs to support nesting -- this means the enumeration needs to be recursive.
515The code below shows the ArithmeticExpression recursive enumeration being created for (5 + 4) * 2:
516\begin{lstlisting}[language=swift]
517let five = ArithmeticExpression.number(5)
518let four = ArithmeticExpression.number(4)
519let sum = ArithmeticExpression.addition(five, four)
520let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
521\end{lstlisting}
522A recursive function is a straightforward way to work with data that has a recursive structure.
523For example, here's a function that evaluates an arithmetic expression:
524\begin{lstlisting}[language=swift]
525func evaluate(_ expression: ArithmeticExpression) -> Int {
526    switch expression {
527    case let .number(value):
528        return value
529    case let .addition(left, right):
530        return evaluate(left) + evaluate(right)
531    case let .multiplication(left, right):
532        return evaluate(left) * evaluate(right)
533    }
534}
535
536print(evaluate(product))
537// Prints "18"
538\end{lstlisting}
539This function evaluates a plain number by simply returning the associated value.
540It evaluates an addition or multiplication by evaluating the expression on the left-hand side, evaluating the expression on the right-hand side, and then adding them or multiplying them.
541
542
543\section{\CC}
544\label{s:C++RelatedWork}
545
546\CC is backwards compatible with C, so it inherited C's enumerations.
547However, the following non-backwards compatible changes have been made.
548\begin{quote}
5497.2 Change: \CC objects of enumeration type can only be assigned values of the same enumeration type.
550In C, objects of enumeration type can be assigned values of any integral type. \\
551Example:
552\begin{lstlisting}[language=c++]
553enum color { red, blue, green };
554color c = 1;                                                    $\C{// valid C, invalid C++}$
555\end{lstlisting}
556\textbf{Rationale}: The type-safe nature of C++. \\
557\textbf{Effect on original feature}: Deletion of semantically well-defined feature. \\
558\textbf{Difficulty of converting}: Syntactic transformation. (The type error produced by the assignment can be automatically corrected by applying an explicit cast.) \\
559\textbf{How widely used}: Common.
560\end{quote}
561\begin{quote}
5627.2 Change: In \CC, the type of an enumerator is its enumeration.
563In C, the type of an enumerator is @int@. \\
564Example:
565\begin{lstlisting}[language=c++]
566enum e { A };
567sizeof(A) == sizeof(int)                                $\C{// in C}$
568sizeof(A) == sizeof(e)                                  $\C{// in C++}$
569/* and sizeof(int) is not necessary equal to sizeof(e) */
570\end{lstlisting}
571\textbf{Rationale}: In C++, an enumeration is a distinct type. \\
572\textbf{Effect on original feature}: Change to semantics of well-defined feature. \\
573\textbf{Difficulty of converting}: Semantic transformation. \\
574\textbf{How widely used}: Seldom. The only time this affects existing C code is when the size of an enumerator is taken.
575Taking the size of an enumerator is not a common C coding practice.
576\end{quote}
577Hence, the values in a \CC enumeration can only be its enumerators (without a cast).
578While the storage size of an enumerator is up to the compiler, there is still an implicit cast to @int@.
579\begin{lstlisting}[language=c++]
580enum E { A, B, C };
581E e = A;
582int i = A;   i = e;                                             $\C{// implicit casts to int}$
583\end{lstlisting}
584\CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), so the enumerators are local to the enumeration and must be accessed using type qualification.
585\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
586enum class E { A, B, C };
587E e = @E::@A;                                                   $\C{// qualified enumerator}$
588e = B;                                                                  $\C{// B not in scope}$
589\end{lstlisting}
590\CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration.
591\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
592enum class E { A, B, C };
593@using enum E;@
594E e = A;                                                                $\C{// direct access}$
595e = B;                                                                  $\C{// direct access}$
596\end{lstlisting}
597\CC{11} added the ability to explicitly declare the underlying integral type for \lstinline[language=c++]{enum class}.
598\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
599enum class RGB @: long@ { Red, Green, Blue };
600enum class rgb @: char@ { Red = 'r', Green = 'g', Blue = 'b' };
601enum class srgb @: signed char@ { Red = -1, Green = 0, Blue = 1 };
602\end{lstlisting}
603There is no implicit conversion from the \lstinline[language=c++]{enum class} type and to its type.
604\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
605rgb crgb = rgb::Red;
606char ch = rgb::Red;   ch = crgb;                $\C{// disallowed}$
607\end{lstlisting}
608Finally, there is no mechanism to iterate through an enumeration nor use the enumeration type to declare an array dimension.
609
610
611\section{Go}
612
613\section{Java}
614
615\section{Modula-3}
616
617\section{Rust}
618
619\section{Swift}
620
621\section{Python}
622
623\section{Algebraic Data Type}
Note: See TracBrowser for help on using the repository browser.