Enumerations: Difference between revisions
m (→{{header|C}}) |
m (→{{header|Wren}}: Minor tidy) |
||
(98 intermediate revisions by 51 users not shown) | |||
Line 1: | Line 1: | ||
{{task|Basic language learning}} |
{{task|Basic language learning}} |
||
;Task: |
|||
Create an enumeration of constants with and without explicit values. |
Create an enumeration of constants with and without explicit values. |
||
<br><br> |
|||
=={{header|11l}}== |
|||
<syntaxhighlight lang="11l">T.enum TokenCategory |
|||
NAME |
|||
KEYWORD |
|||
CONSTANT |
|||
TEST_CATEGORY = 10</syntaxhighlight> |
|||
=={{header|6502 Assembly}}== |
|||
===With Explicit Values=== |
|||
You can use labels to "name" any numeric value, whether it represents a constant or a memory location is up to the programmer. Code labels are automatically assigned a value based on what memory location they are assembled to. |
|||
Keep in mind that these names do not exist at runtime and are just for the programmer's convenience. None of this "code" below actually takes up any space in the assembled program. |
|||
<syntaxhighlight lang="6502asm">Sunday equ 0 |
|||
Monday equ 1 |
|||
Tuesday equ 2 |
|||
Wednesday equ 3 |
|||
Thursday equ 4 |
|||
Friday equ 5 |
|||
Saturday equ 6</syntaxhighlight> |
|||
Some assemblers have an actual <code>ENUM</code> directive, where only the 0th element needs a defined value and the rest follow sequentially. This is often used for allocating RAM locations rather than a [[C]]-style enumeration, however. <code>.DSB</code> is a directive that stands for "data storage byte" and is listed after the label so that the assembler knows how big the variable is. In the example below the variable <code>OBJECT_XPOS</code> begins at $0400 and <code>OBJECT_XPOS</code> begins at $0410: |
|||
<syntaxhighlight lang="6502asm">enum $0400 |
|||
OBJECT_XPOS .dsb 16 ;define 16 bytes for object X position |
|||
OBJECT_YPOS .dsb 16 ;define 16 bytes for object Y position |
|||
ende</syntaxhighlight> |
|||
===Without Explicit Values=== |
|||
A lookup table is the most common method of enumeration of actual data in assembly. Each element of the table can be accessed by an index, and the starting index is zero. (The index may need to be adjusted for data sizes larger than 1 byte, i.e. doubled for 16-bit data and quadrupled for 32-bit data.) Unlike the above example, these values do indeed take up memory. Using this method when the above enumeration would suffice is incredibly wasteful. |
|||
<syntaxhighlight lang="6502asm">Days_Of_The_Week: |
|||
word Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday |
|||
Sunday: |
|||
byte "Sunday",0 |
|||
Monday: |
|||
byte "Monday",0 |
|||
Tuesday: |
|||
byte "Tuesday",0 |
|||
Wednesday: |
|||
byte "Wednesday",0 |
|||
Thursday: |
|||
byte "Thursday",0 |
|||
Friday: |
|||
byte "Friday",0 |
|||
Saturday: |
|||
byte "Saturday",0 |
|||
LDA #$03 ;we want to load Wednesday |
|||
ASL A ;these are 16-bit pointers to strings, so double A |
|||
TAX ;transfer A to X so that we can use this index as a lookup |
|||
LDA Days_Of_The_Week,x ;get low byte |
|||
STA $00 ;store in zero page memory |
|||
LDA Days_Of_The_Week+1,x ;get high byte |
|||
STA $01 ;store in zero page memory directly after low byte |
|||
LDY #0 ;clear Y |
|||
LDA ($00),Y ;Load the "W" of Wednesday into accumulator</syntaxhighlight> |
|||
=={{header|68000 Assembly}}== |
|||
{{trans|6502 Assembly}} |
|||
===With Explicit Values=== |
|||
You can use labels to "name" any numeric value, whether it represents a constant or a memory location is up to the programmer. Code labels are automatically assigned a value based on what memory location they are assembled to. The syntax for labels depends on your assembler; the example below uses VASM syntax and Motorola mnemonics. |
|||
Keep in mind that these names do not exist at runtime and are just for the programmer's convenience. None of this "code" below actually takes up any space in the assembled program. |
|||
<syntaxhighlight lang="68000devpac">Sunday equ 0 |
|||
Monday equ 1 |
|||
Tuesday equ 2 |
|||
Wednesday equ 3 |
|||
Thursday equ 4 |
|||
Friday equ 5 |
|||
Saturday equ 6</syntaxhighlight> |
|||
===Without Explicit Values=== |
|||
A lookup table is the most common method of enumeration of actual data in assembly. Each element of the table can be accessed by an index, and the starting index is zero. (The index may need to be adjusted for data sizes larger than 1 byte, i.e. doubled for 16-bit data and quadrupled for 32-bit data.) Unlike the above example, these values do indeed take up memory. Using this method when the above enumeration would suffice is incredibly wasteful. |
|||
Like in a [[C]]-style enumeration, Sunday would be 0, Monday 1, Tuesday 2, and so on. (Actually, Monday would be 4 and Tuesday would be 8 and so on, since these are 32-bit pointers.) It's a common practice to have the index live in RAM as a one-byte index, load it in a register, and then scale its register copy during the lookup process only. That way if multiple tables with different data sizes have a common index, the program doesn't need to remember which data type the index was last used to access. |
|||
<syntaxhighlight lang="68000devpac">Days_Of_The_Week: |
|||
DC.L Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday |
|||
Sunday: |
|||
DC.B "Sunday",0 |
|||
EVEN ;conditionally aligns to a 2-byte boundary if the data isn't aligned already |
|||
Monday: |
|||
DC.B "Monday",0 |
|||
EVEN |
|||
Tuesday: |
|||
DC.B "Tuesday",0 |
|||
EVEN |
|||
Wednesday: |
|||
DC.B "Wednesday",0 |
|||
EVEN |
|||
Thursday: |
|||
DC.B "Thursday",0 |
|||
EVEN |
|||
Friday: |
|||
DC.B "Friday",0 |
|||
EVEN |
|||
Saturday: |
|||
DC.B "Saturday",0 |
|||
EVEN |
|||
;In this example, load Thursday. |
|||
LEA Days_Of_The_Week,A0 ;load base address of table into A0 |
|||
MOVE.W #4,D0 ;Thursday's index |
|||
LSL.W #2,D0 ;multiply by 4 since each pointer is 32-bit |
|||
LEA (A0,D0),A1 ;load table offset by D0 into A1 |
|||
MOVE.L (A1),A1 ;dereference the pointer, now the address of "Thursday" is in A1. |
|||
MOVE.B (A1)+,D1 ;Load the "T" of Thursday into D1, auto-increment to next letter for the next load.</syntaxhighlight> |
|||
=={{header|8086 Assembly}}== |
|||
{{trans|6502 Assembly}} |
|||
===With Explicit Values=== |
|||
Most assemblers allow the use of an <code>equ</code> directive or something similar, where you can assign a label to a number for later use. These do not take up space in your program. |
|||
<syntaxhighlight lang="asm">Sunday equ 0 |
|||
Monday equ 1 |
|||
Tuesday equ 2 |
|||
Wednesday equ 3 |
|||
Thursday equ 4 |
|||
Friday equ 5 |
|||
Saturday equ 6 |
|||
Sunday equ 7</syntaxhighlight> |
|||
===Without Explicit Values=== |
|||
A lookup table is often used to translate data according to a common index. The <code>XLAT</code> instruction can help us with this task, however that instruction only works with 8-bit data, which is not always what we're after. In this example, we're using numbers 0 through 7 to look up a table of pointers to strings. When declaring a table like this, these DO take up space in your program. |
|||
<syntaxhighlight lang="asm">mov ax,seg DaysOfTheWeek |
|||
mov ds,ax |
|||
mov si,offset DaysOfTheWeek |
|||
mov bx,2 ;desired enumeration of 2 = Tuesday |
|||
add bx,bx ;double bx since this is a table of words |
|||
mov ax,[bx+si] ;load the address of the string "Tuesday" into ax |
|||
mov si,ax ;we can't load indirectly from AX, so move it into SI. We don't need the old value of SI anymore |
|||
mov al,[si] ;load the byte at [SI] (in this case, the "T" in Tuesday.) |
|||
ret |
|||
DaysOfTheWeek word Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday |
|||
;each is a pointer to a string containing the text you would expect.</syntaxhighlight> |
|||
=={{header|ACL2}}== |
=={{header|ACL2}}== |
||
Line 7: | Line 153: | ||
ACL2 doesn't have built-in enumerated types, but these macros add some basic support: |
ACL2 doesn't have built-in enumerated types, but these macros add some basic support: |
||
< |
<syntaxhighlight lang="lisp">(defun symbol-to-constant (sym) |
||
(intern (concatenate 'string "*" (symbol-name sym) "*") |
(intern (concatenate 'string "*" (symbol-name sym) "*") |
||
"ACL2")) |
"ACL2")) |
||
Line 28: | Line 174: | ||
(defmacro enum (&rest symbols) |
(defmacro enum (&rest symbols) |
||
`(enum-with-vals ,@(interleave-with-nats symbols)))</ |
`(enum-with-vals ,@(interleave-with-nats symbols)))</syntaxhighlight> |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
Ada enumeration types have three distinct attributes, the enumeration literal, the enumeration position, and the representation value. The position value (starting with 0) is implied from the order of specification of the enumeration literals in the type declaration; it provides the ordering for the enumeration values. In the example below, apple (position 0) is less than banana (position 1) which is less than cherry (position 3) due to their positions, not due to their enumeration literal. An enumeration representation, when given, must not violate the order. |
Ada enumeration types have three distinct attributes, the enumeration literal, the enumeration position, and the representation value. The position value (starting with 0) is implied from the order of specification of the enumeration literals in the type declaration; it provides the ordering for the enumeration values. In the example below, apple (position 0) is less than banana (position 1) which is less than cherry (position 3) due to their positions, not due to their enumeration literal. An enumeration representation, when given, must not violate the order. |
||
< |
<syntaxhighlight lang="ada">type Fruit is (apple, banana, cherry); -- No specification of the representation value; |
||
for Fruit use (apple => 1, banana => 2, cherry => 4); -- specification of the representation values</ |
for Fruit use (apple => 1, banana => 2, cherry => 4); -- specification of the representation values</syntaxhighlight> |
||
Ada enumeration types are non-numeric discrete types. They can be used to index arrays, but there are no arithmetic operators for enumeration types; instead, there are predecessor and successor operations. Characters are implemented as an enumeration type in Ada. |
Ada enumeration types are non-numeric discrete types. They can be used to index arrays, but there are no arithmetic operators for enumeration types; instead, there are predecessor and successor operations. Characters are implemented as an enumeration type in Ada. |
||
Line 49: | Line 195: | ||
compatible with INT and so FRUITS inherit/share all INT's operators |
compatible with INT and so FRUITS inherit/share all INT's operators |
||
and procedures. |
and procedures. |
||
< |
<syntaxhighlight lang="algol68">BEGIN # example 1 # |
||
MODE FRUIT = INT; |
MODE FRUIT = INT; |
||
FRUIT apple = 1, banana = 2, cherry = 4; |
FRUIT apple = 1, banana = 2, cherry = 4; |
||
Line 61: | Line 207: | ||
SKIP # other values # |
SKIP # other values # |
||
ESAC |
ESAC |
||
END;</ |
END;</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
It is a cherry # +4 |
It is a cherry # +4 |
||
Line 78: | Line 224: | ||
least REPR (or ABS for INT type) must be defined if anything other then a |
least REPR (or ABS for INT type) must be defined if anything other then a |
||
'''case''' conditional clause is required. |
'''case''' conditional clause is required. |
||
< |
<syntaxhighlight lang="algol68">BEGIN # example 2 # |
||
MODE ENUM = [0]CHAR; # something with minimal size # |
MODE ENUM = [0]CHAR; # something with minimal size # |
||
MODE APPLE = STRUCT(ENUM apple), BANANA = STRUCT(ENUM banana), CHERRY = STRUCT(ENUM cherry); |
MODE APPLE = STRUCT(ENUM apple), BANANA = STRUCT(ENUM banana), CHERRY = STRUCT(ENUM cherry); |
||
Line 101: | Line 247: | ||
SKIP # uninitialised FRUIT # |
SKIP # uninitialised FRUIT # |
||
ESAC |
ESAC |
||
END</ |
END</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
It is a Cherry |
It is a Cherry |
||
Line 111: | Line 257: | ||
=={{header|AmigaE}}== |
=={{header|AmigaE}}== |
||
< |
<syntaxhighlight lang="amigae">ENUM APPLE, BANANA, CHERRY |
||
PROC main() |
PROC main() |
||
Line 117: | Line 263: | ||
ForAll({x}, [APPLE, BANANA, CHERRY], |
ForAll({x}, [APPLE, BANANA, CHERRY], |
||
`WriteF('\d\n', x)) |
`WriteF('\d\n', x)) |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
writes 0, 1, 2 to the console. |
writes 0, 1, 2 to the console. |
||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">enum: [apple banana cherry] |
|||
print "as a block of words:" |
|||
inspect.muted enum |
|||
enum: ['apple 'banana 'cherry] |
|||
print "\nas a block of literals:" |
|||
print enum |
|||
enum: #[ |
|||
apple: 1 |
|||
banana: 2 |
|||
cherry: 3 |
|||
] |
|||
print "\nas a dictionary:" |
|||
print enum</syntaxhighlight> |
|||
{{out}} |
|||
<pre>as a block of words: |
|||
[ :block |
|||
apple :word |
|||
banana :word |
|||
cherry :word |
|||
] |
|||
as a block of literals: |
|||
apple banana cherry |
|||
as a dictionary: |
|||
[apple:1 banana:2 cherry:3]</pre> |
|||
=={{header|ATS}}== |
|||
The wording of the task seems centered on C, where an '''enum''' is a notation for type '''int''', but it is true that the following type will be translated by the ATS compiler to C integers: |
|||
<syntaxhighlight lang="ats">datatype my_enum = |
|||
| value_a |
|||
| value_b |
|||
| value_c</syntaxhighlight> |
|||
Within ATS itself, '''my_enum''' is a special case of recursive type definition. Similar facilities are available in ML dialects and other languages. |
|||
To "enumerate" with explicit integer values, I would simply define some constants, probably with '''#define''' (so I could use them in static expressions, etc.): |
|||
<syntaxhighlight lang="ats">#define value_a 1 |
|||
#define value_b 2 |
|||
#define value_c 3</syntaxhighlight> |
|||
You could still restrict things so no other values were possible: |
|||
<syntaxhighlight lang="ats">typedef my_enum = [i : int | value_a <= i; i <= value_c] int i</syntaxhighlight> |
|||
The value of a '''my_enum''' would be enforced ''at compile time''. |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
AutoHotkey doesn't really enforce types. <br> |
AutoHotkey doesn't really enforce types. <br> |
||
However you can simulate types like enumeration with associative arrays: |
However you can simulate types like enumeration with associative arrays: |
||
< |
<syntaxhighlight lang="autohotkey">fruit_%apple% = 0 |
||
fruit_%banana% = 1 |
fruit_%banana% = 1 |
||
fruit_%cherry% = 2</ |
fruit_%cherry% = 2</syntaxhighlight> |
||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
In awk we can use an array, for mapping both ways, or initialize variables: |
In awk we can use an array, for mapping both ways, or initialize variables: |
||
< |
<syntaxhighlight lang="awk">fruit["apple"]=1; fruit["banana"]=2; fruit["cherry"]=3 |
||
fruit[1]="apple"; fruit[2]="banana"; fruit[3]="cherry" |
fruit[1]="apple"; fruit[2]="banana"; fruit[3]="cherry" |
||
i=0; apple=++i; banana=++i; cherry=++i;</ |
i=0; apple=++i; banana=++i; cherry=++i;</syntaxhighlight> |
||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
Line 137: | Line 339: | ||
{{works with|PB|7.1}} |
{{works with|PB|7.1}} |
||
< |
<syntaxhighlight lang="qbasic">REM Impossible. Can only be faked with arrays of strings. |
||
OPTION BASE 1 |
OPTION BASE 1 |
||
DIM SHARED fruitsName$(1 to 3) |
DIM SHARED fruitsName$(1 to 3) |
||
Line 152: | Line 354: | ||
apple% = 1 |
apple% = 1 |
||
banana% = 2 |
banana% = 2 |
||
cherry% = 3</ |
cherry% = 3</syntaxhighlight> |
||
==={{header|BaCon}}=== |
|||
BaCon includes an ENUM statement, with or without fixed values. If no value is given, enumerations start at zero and increase by integer 1. |
|||
<syntaxhighlight lang="freebasic">' Enumerations |
|||
' Start at zero |
|||
ENUM |
|||
cat, dog, parrot |
|||
END ENUM |
|||
PRINT "Dogs are #", dog |
|||
' Set value |
|||
ENUM |
|||
Sunday=1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday |
|||
END ENUM |
|||
PRINT Sunday, " ", Wednesday, " ", Saturday |
|||
' Change values, ENUM names must be unique |
|||
ENUM |
|||
sunday=7, monday=1, tuesday, wednesday, thursday, friday, saturday |
|||
END ENUM |
|||
PRINT sunday, " ", wednesday, " ", saturday</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ ./enums |
|||
Dogs are #1 |
|||
1 4 7 |
|||
7 3 6</pre> |
|||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
Line 159: | Line 389: | ||
'Create a collection of constants that is a complete, ordered listing of all of the constants in that collection, with and without explicit values.' |
'Create a collection of constants that is a complete, ordered listing of all of the constants in that collection, with and without explicit values.' |
||
In Bracmat, each expression is a constant and can be used in situations where one would use an enum in other languages. All expressions have an ordering in sums and products. In the case of non-numeric strings the ordering is alphabetic. It is not possible in Bracmat to have a constant without an explicit value, because the constant is nothing but the value, so only half of the task can be solved. |
In Bracmat, each expression is a constant and can be used in situations where one would use an enum in other languages. All expressions have an ordering in sums and products. In the case of non-numeric strings the ordering is alphabetic. It is not possible in Bracmat to have a constant without an explicit value, because the constant is nothing but the value, so only half of the task can be solved. |
||
< |
<syntaxhighlight lang="bracmat">fruits=apple+banana+cherry;</syntaxhighlight> |
||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<syntaxhighlight lang="c">enum fruits { apple, banana, cherry }; |
||
enum fruits { apple = 0, banana = 1, cherry = 2 };</ |
enum fruits { apple = 0, banana = 1, cherry = 2 };</syntaxhighlight> |
||
However, if defined like the above, in C you must use the type as <code>enum fruits</code>, not just <code>fruits</code>. A common practice in C (same with <code>struct</code>s) is to instead typedef the enum so you can refer to the type as a bare name: |
However, if defined like the above, in C you must use the type as <code>enum fruits</code>, not just <code>fruits</code>. A common practice in C (same with <code>struct</code>s) is to instead typedef the enum so you can refer to the type as a bare name: |
||
< |
<syntaxhighlight lang="c">typedef enum { apple, banana, cherry } fruits; |
||
typedef enum { apple = 0, banana = 1, cherry = 2 } fruits;</ |
typedef enum { apple = 0, banana = 1, cherry = 2 } fruits;</syntaxhighlight> |
||
=={{header|C++}}== |
|||
<lang cpp>enum fruits { apple, banana, cherry }; |
|||
enum fruits { apple = 0, banana = 1, cherry = 2 };</lang> |
|||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang="csharp">enum fruits { apple, banana, cherry } |
||
enum fruits { apple = 0, banana = 1, cherry = 2 } |
enum fruits { apple = 0, banana = 1, cherry = 2 } |
||
Line 185: | Line 410: | ||
[FlagsAttribute] |
[FlagsAttribute] |
||
enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 }</ |
enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 }</syntaxhighlight> |
||
Placing FlagsAttribute before an enum allows you to perform bitwise operations on the value. |
Placing FlagsAttribute before an enum allows you to perform bitwise operations on the value. |
||
Note: All enums have a value of 0 defined, even if not specified in the set values. |
Note: All enums have a value of 0 defined, even if not specified in the set values. |
||
=={{header|C++}}== |
|||
<syntaxhighlight lang="cpp">enum fruits { apple, banana, cherry }; |
|||
enum fruits { apple = 0, banana = 1, cherry = 2 };</syntaxhighlight> |
|||
Note that, unlike in C, you can refer to the type here as <code>fruits</code>. |
|||
---- |
|||
{{works with|C++11}} |
|||
C++11 introduced "strongly typed enumerations", enumerations that cannot be implicitly converted to/from integers: |
|||
<syntaxhighlight lang="cpp">enum class fruits { apple, banana, cherry }; |
|||
enum class fruits { apple = 0, banana = 1, cherry = 2 };</syntaxhighlight> |
|||
These enumeration constants must be referred to as <code>fruits::apple</code>, not just <code>apple</code>. |
|||
You can explicitly specify an underlying type for the enum; the default is <code>int</code>: |
|||
<syntaxhighlight lang="cpp">enum class fruits : unsigned int { apple, banana, cherry };</syntaxhighlight> |
|||
You can also explicitly specify an underlying type for old-style enums: |
|||
<syntaxhighlight lang="cpp">enum fruits : unsigned int { apple, banana, cherry };</syntaxhighlight> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
In Clojure you will typically use keywords when you would use enums in other languages. Keywords are symbols that start with a colon and evaluate to themselves. For example: |
In Clojure you will typically use keywords when you would use enums in other languages. Keywords are symbols that start with a colon and evaluate to themselves. For example: |
||
< |
<syntaxhighlight lang="clojure">; a set of keywords |
||
(def fruits #{:apple :banana :cherry}) |
(def fruits #{:apple :banana :cherry}) |
||
Line 202: | Line 448: | ||
(println (fruit? :apple)) |
(println (fruit? :apple)) |
||
(println (fruit-value :banana))</ |
(println (fruit-value :banana))</syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Values: |
Values: |
||
< |
<syntaxhighlight lang="lisp">;; symbol to number |
||
(defconstant +apple+ 0) |
(defconstant +apple+ 0) |
||
(defconstant +banana+ 1) |
(defconstant +banana+ 1) |
||
Line 214: | Line 460: | ||
;; number to symbol |
;; number to symbol |
||
(defun index-fruit (i) |
(defun index-fruit (i) |
||
(aref #(+apple+ +banana+ +cherry+) i))</ |
(aref #(+apple+ +banana+ +cherry+) i))</syntaxhighlight> |
||
Of course, the two definitions above can be produced by a single macro, if desired. |
Of course, the two definitions above can be produced by a single macro, if desired. |
||
Defining a type for documentation or checking purposes: |
Defining a type for documentation or checking purposes: |
||
< |
<syntaxhighlight lang="lisp">(deftype fruit () |
||
'(member +apple+ +banana+ +cherry+))</ |
'(member +apple+ +banana+ +cherry+))</syntaxhighlight> |
||
=={{header|Computer/zero Assembly}}== |
|||
Constants can be defined by simply storing their binary representation into memory. You've only got 32 bytes of RAM so don't waste them. This is the only way to use numeric values, as all instructions on the CPU take memory addresses as operands, not constants. |
|||
<syntaxhighlight lang="6502asm">LDA 4 ;load from memory address 4 |
|||
STP |
|||
NOP |
|||
NOP |
|||
byte 1</syntaxhighlight> |
|||
The <code>NOP</code> and <code>STP</code> instructions ignore their operands, which means you can store arbitrary data inside those instructions that you can load from. This can save a little bit of memory. |
|||
=={{header|D}}== |
=={{header|D}}== |
||
<syntaxhighlight lang="d">void main() { |
|||
<lang d>// Named (commonly used enum in D) (int). |
|||
// Named enumeration (commonly used enum in D). |
|||
enum Fruits1 { apple, banana, cherry } |
|||
// The underlying type is a 32 bit int. |
|||
enum Fruits1 { apple, banana, cherry } |
|||
// You can assign an enum to the general type, but not the opposite: |
|||
// Anonymous, as in C. |
|||
int f1 = Fruits1.banana; // No error. |
|||
enum { APPLE, BANANA, CHERRY } |
|||
// Fruits1 f2 = 1; // Error: cannot implicitly convert. |
|||
// Anonymous enumeration, as in C, of type 32 bit int. |
|||
// Named with specified values (int). |
|||
enum { APPLE, BANANA, CHERRY } |
|||
enum Fruits2 { apple = 0, banana = 10, cherry = 20 } |
|||
static assert(CHERRY == 2); |
|||
// Named |
// Named enumeration with specified values (int). |
||
enum Fruits2 { apple = 0, banana = 10, cherry = 20 } |
|||
// Named enumeration, typed and with specified values. |
|||
void main() { |
|||
enum Fruits3 : ubyte { apple = 0, banana = 100, cherry = 200 } |
|||
static assert(CHERRY == 2); |
|||
int f1 = Fruits2.banana; // No error. |
|||
// Named enumeration, typed and with partially specified values. |
|||
// Fruits2 f2 = 1; // Error: cannot implicitly convert. |
|||
enum Test : ubyte { A = 2, B, C = 3 } |
|||
}</lang> |
|||
static assert(Test.B == 3); // Uses the next ubyte, duplicated value. |
|||
// This raises a compile-time error for overflow. |
|||
// enum Fruits5 : ubyte { apple = 254, banana = 255, cherry } |
|||
enum Component { |
|||
none, |
|||
red = 2 ^^ 0, |
|||
green = 2 ^^ 1, |
|||
blue = 2 ^^ 2 |
|||
} |
|||
// Phobos BitFlags support all the most common operations on flags. |
|||
// Some of the operations are shown below. |
|||
import std.typecons: BitFlags; |
|||
alias ComponentFlags = BitFlags!Component; |
|||
immutable ComponentFlags flagsEmpty; |
|||
// Value can be set with the | operator. |
|||
immutable flagsRed = flagsEmpty | Component.red; |
|||
immutable flagsGreen = ComponentFlags(Component.green); |
|||
immutable flagsRedGreen = ComponentFlags(Component.red, Component.green); |
|||
immutable flagsBlueGreen = ComponentFlags(Component.blue, Component.green); |
|||
// Use the & operator between BitFlags for intersection. |
|||
assert (flagsGreen == (flagsRedGreen & flagsBlueGreen)); |
|||
}</syntaxhighlight> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
In addition to [[#Pascal|standard Pascal]], one may explicitly specify an index: |
|||
<syntaxhighlight lang="delphi">type |
|||
fruit = (apple, banana, cherry); |
|||
ape = (gorilla = 0, chimpanzee = 1, orangutan = 5);</syntaxhighlight> |
|||
Note, explicit indices ''have'' to be in ascending order. |
|||
You can also just specify explicit indices for ''some'' items. |
|||
=={{header|Diego}}== |
|||
<lang Delphi>type |
|||
Enumerations can have extra information appended such as <code>static</code> (static variable name); <code>colour</code> (human friendly colour name); <code>color</code> (robot friendly colour name); and <code>desc</code> (description used for robots to communicate with humans). |
|||
TFruit = (Apple, Banana, Cherry); |
|||
With explicit values: |
|||
TApe = (Gorilla = 0, Chimpanzee = 1, Orangutan = 5);</lang> |
|||
<syntaxhighlight lang="diego">add_enum(⟪{int}⟫,⟦{str}⟧,urgency) |
|||
()_enum(⟪4⟫,⟦emergent⟧)_static(URGENCY_EMERGENT)_colour(red)_color({hex},#ca0031)_desc(The most urgent (critical) state, severe risk.); |
|||
()_enum(⟪3⟫,⟦exigent⟧)_static(URGENT_EXIGENT)_colour(orange)_color({hex},#ff6400)_desc(The high urgent state, high risk.); |
|||
()_enum(⟪2⟫,⟦urgent⟧)_static(URGENT_URGENT)_colour(yellow)_color({hex},#fce001)_desc(The elevated urgent state, elevated risk.); |
|||
()_enum(⟪1⟫,⟦infergent⟧)_static(URGENT_INFERGENT)_colour(blue)_color({hex},#3566cd)_desc(The low urgent state, low / guarded risk.); |
|||
()_enum(⟪0⟫,⟦nonurgent⟧)_static(URGENT_NON)_colour(green)_color({hex},#009a66)_desc(The non-urgent state, negligible risk.); |
|||
;</syntaxhighlight> |
|||
Without explicit values (and dynamic typing): |
|||
<syntaxhighlight lang="diego">add_enum(fruits,⟦apple,banana,cherry⟧);</syntaxhighlight> |
|||
Flag enumerations (multi-selectable enumerations) can be created using <code>enum</code>, however, there is an primitive <code>flag</code> object available. This is similar to <code>[Flags]</code> and <code><Flags> _</code> flag attributes in C# and VB.Net respectively. |
|||
<syntaxhighlight lang="diego">add_flag(ape,⟦gorilla,chimpanzee,orangutan⟧); |
|||
log_console()_(ape);</syntaxhighlight> |
|||
Output: |
|||
<pre>⟪1⟫,⟦gorilla⟧,⟪2⟫,⟦chimpanzee⟧,⟪4⟫,⟦orangutan⟧</pre> |
|||
=={{header|DWScript}}== |
=={{header|DWScript}}== |
||
< |
<syntaxhighlight lang="delphi">type TFruit = (Apple, Banana, Cherry); |
||
type TApe = (Gorilla = 0, Chimpanzee = 1, Orangutan = 5);</ |
type TApe = (Gorilla = 0, Chimpanzee = 1, Orangutan = 5);</syntaxhighlight> |
||
=={{header|E}}== |
=={{header|E}}== |
||
Simple group of object definitions (value methods could be left out if appropriate): |
Simple group of object definitions (value methods could be left out if appropriate): |
||
< |
<syntaxhighlight lang="e">def apple { to value() { return 0 } } |
||
def banana { to value() { return 1 } } |
def banana { to value() { return 1 } } |
||
def cherry { to value() { return 2 } }</ |
def cherry { to value() { return 2 } }</syntaxhighlight> |
||
With a guard for type checks: |
With a guard for type checks: |
||
< |
<syntaxhighlight lang="e">interface Fruit guards FruitStamp {} |
||
def apple implements FruitStamp {} |
def apple implements FruitStamp {} |
||
def banana implements FruitStamp {} |
def banana implements FruitStamp {} |
||
def cherry implements FruitStamp {} |
def cherry implements FruitStamp {} |
||
def eat(fruit :Fruit) { ... }</ |
def eat(fruit :Fruit) { ... }</syntaxhighlight> |
||
With and without values, using a hypothetical enumeration library: |
With and without values, using a hypothetical enumeration library: |
||
< |
<syntaxhighlight lang="e">def [Fruit, [=> apple, => banana, => cherry]] := makeEnumeration() |
||
def [Fruit, [=> apple, => banana, => cherry]] := |
def [Fruit, [=> apple, => banana, => cherry]] := |
||
makeEnumeration(0, ["apple", "banana", "cherry"])</ |
makeEnumeration(0, ["apple", "banana", "cherry"])</syntaxhighlight> |
||
=={{header|EGL}}== |
=={{header|EGL}}== |
||
{{works with|EDT}} |
{{works with|EDT}} |
||
< |
<syntaxhighlight lang="egl">// Without explicit values |
||
enumeration FruitsKind |
enumeration FruitsKind |
||
APPLE, |
APPLE, |
||
Line 301: | Line 612: | ||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
{{works with|EDT}} |
{{works with|EDT}} |
||
-and- |
-and- |
||
{{works with|RBD}} |
{{works with|RBD}} |
||
< |
<syntaxhighlight lang="egl">// With explicit values |
||
library FruitsKind type BasicLibrary {} |
library FruitsKind type BasicLibrary {} |
||
const APPLE int = 0; |
const APPLE int = 0; |
||
Line 332: | Line 643: | ||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Elixir}}== |
|||
It is possible to use a atom if the value is unrelated. |
|||
<syntaxhighlight lang="elixir">fruits = [:apple, :banana, :cherry] |
|||
fruits = ~w(apple banana cherry)a # Above-mentioned different notation |
|||
val = :banana |
|||
Enum.member?(fruits, val) #=> true |
|||
val in fruits #=> true</syntaxhighlight> |
|||
If they have to have a specific value |
|||
<syntaxhighlight lang="elixir">fruits = [{:apple, 1}, {:banana, 2}, {:cherry, 3}] # Keyword list |
|||
fruits = [apple: 1, banana: 2, cherry: 3] # Above-mentioned different notation |
|||
fruits[:apple] #=> 1 |
|||
Keyword.has_key?(fruits, :banana) #=> true |
|||
fruits = %{:apple=>1, :banana=>2, :cherry=>3} # Map |
|||
fruits = %{apple: 1, banana: 2, cherry: 3} # Above-mentioned different notation |
|||
fruits[:apple] #=> 1 |
|||
fruits.apple #=> 1 (Only When the key is Atom) |
|||
Map.has_key?(fruits, :banana) #=> true</syntaxhighlight> |
|||
To give a number in turn, there is the following method. |
|||
<syntaxhighlight lang="elixir"># Keyword list |
|||
fruits = ~w(apple banana cherry)a |> Enum.with_index |
|||
#=> [apple: 0, banana: 1, cherry: 2] |
|||
# Map |
|||
fruits = ~w(apple banana cherry)a |> Enum.with_index |> Map.new |
|||
#=> %{apple: 0, banana: 1, cherry: 2}</syntaxhighlight> |
|||
=={{header|EMal}}== |
|||
<syntaxhighlight lang="emal"> |
|||
in Org:RosettaCode |
|||
type Fruits |
|||
enum |
|||
int APPLE, BANANA, CHERRY |
|||
end |
|||
type ExplicitFruits |
|||
enum |
|||
int APPLE = 10 |
|||
int BANANA = 20 |
|||
int CHERRY = 1 |
|||
end |
|||
type Main |
|||
for each generic enumeration in generic[Fruits, ExplicitFruits] |
|||
writeLine("[" + Generic.name(enumeration) + "]") |
|||
writeLine("getting an object with value = 1:") |
|||
writeLine(:enumeration.byValue(1)) |
|||
writeLine("iterating over the items:") |
|||
for each var fruit in :enumeration |
|||
writeLine(fruit) |
|||
end |
|||
writeLine() |
|||
end |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[Org:RosettaCode:Fruits] |
|||
getting an object with value = 1: |
|||
BANANA(1) |
|||
iterating over the items: |
|||
APPLE(0) |
|||
BANANA(1) |
|||
CHERRY(2) |
|||
[Org:RosettaCode:ExplicitFruits] |
|||
getting an object with value = 1: |
|||
CHERRY(1) |
|||
iterating over the items: |
|||
APPLE(10) |
|||
BANANA(20) |
|||
CHERRY(1) |
|||
</pre> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
For the unspecific value enum use case, Erlang has atoms. You can use apple, banana, orange directly in the code. |
For the unspecific value enum use case, Erlang has atoms. You can use apple, banana, orange directly in the code. |
||
If they have to have a specific value they could be grouped like this: {apple, 1}, {banana, 3}, {orange, 8} |
If they have to have a specific value they could be grouped like this: {apple, 1}, {banana, 3}, {orange, 8} |
||
=={{header|F_Sharp|F#}}== |
|||
Enumerations in F# always have explicit values: |
|||
<syntaxhighlight lang="fsharp">type Fruit = |
|||
| Apple = 0 |
|||
| Banana = 1 |
|||
| Cherry = 2 |
|||
let basket = [ Fruit.Apple ; Fruit.Banana ; Fruit.Cherry ] |
|||
Seq.iter (printfn "%A") basket</syntaxhighlight> |
|||
If the initialization values are omitted, the resulting type is a discriminated union (algebraic data type) instead. |
|||
Simple discriminated unions can be used similarly to enumerations, but they are never convertible from and to integers, and their internal representation is quite different. |
|||
<syntaxhighlight lang="fsharp">type Fruit = |
|||
| Apple |
|||
| Banana |
|||
| Cherry |
|||
let basket = [ Apple ; Banana ; Cherry ] |
|||
Seq.iter (printfn "%A") basket</syntaxhighlight> |
|||
=={{header|Factor}}== |
|||
Enumerations are essentially association lists with values (keys) assigned sequentially from constants (values) provided by an initial sequence. |
|||
<syntaxhighlight lang="factor">IN: scratchpad { "sun" "mon" "tue" "wed" "thur" "fri" "sat" } <enum> |
|||
--- Data stack: |
|||
T{ enum f ~array~ } |
|||
IN: scratchpad [ 1 swap at ] [ keys ] bi |
|||
--- Data stack: |
|||
"mon" |
|||
{ 0 1 2 3 4 5 6 }</syntaxhighlight> |
|||
Factor also provides C-like enumerations in its C library interface. These enumerations may have explicit values. |
|||
<syntaxhighlight lang="factor">IN: scratchpad USE: alien.syntax |
|||
IN: scratchpad ENUM: day sun mon { tue 42 } wed thur fri sat ; |
|||
IN: scratchpad 1 <day> |
|||
--- Data stack: |
|||
mon |
|||
IN: scratchpad 42 <day> |
|||
--- Data stack: |
|||
mon |
|||
tue</syntaxhighlight> |
|||
=={{header|Fantom}}== |
=={{header|Fantom}}== |
||
Line 342: | Line 771: | ||
Enumerations with named constants: |
Enumerations with named constants: |
||
< |
<syntaxhighlight lang="fantom"> |
||
// create an enumeration with named constants |
// create an enumeration with named constants |
||
enum class Fruits { apple, banana, orange } |
enum class Fruits { apple, banana, orange } |
||
</syntaxhighlight> |
|||
</lang> |
|||
A private constructor can be added to initialise internal fields, which must be constant. |
A private constructor can be added to initialise internal fields, which must be constant. |
||
<syntaxhighlight lang="fantom"> |
|||
<lang Fantom> |
|||
// create an enumeration with explicit values |
// create an enumeration with explicit values |
||
enum class Fruits_ |
enum class Fruits_ |
||
Line 357: | Line 786: | ||
private new make (Int value) { this.value = value } |
private new make (Int value) { this.value = value } |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
Forth has no types, and therefore no enumeration type. To define sequential constants, a programmer might write code like this: |
Forth has no types, and therefore no enumeration type. To define sequential constants, a programmer might write code like this: |
||
< |
<syntaxhighlight lang="forth">0 CONSTANT apple |
||
1 CONSTANT banana |
1 CONSTANT banana |
||
2 CONSTANT cherry |
2 CONSTANT cherry |
||
...</ |
...</syntaxhighlight> |
||
However, a common idiom in forth is to define a defining word, such as: |
However, a common idiom in forth is to define a defining word, such as: |
||
< |
<syntaxhighlight lang="forth">: ENUM ( n -<name>- n+1 ) DUP CONSTANT 1+ ;</syntaxhighlight> |
||
This word defines a new constant of the value specified and returns the next value in sequence. |
This word defines a new constant of the value specified and returns the next value in sequence. |
||
It would be used like this: |
It would be used like this: |
||
< |
<syntaxhighlight lang="forth">0 ENUM APPLE ENUM BANANA ENUM CHERRY DROP</syntaxhighlight> |
||
Or you can use CONSTANT to capture the "end" value instead of dropping it: |
Or you can use CONSTANT to capture the "end" value instead of dropping it: |
||
< |
<syntaxhighlight lang="forth">0 ENUM FIRST ENUM SECOND ... CONSTANT LAST</syntaxhighlight> |
||
A variation of this idea is the "stepped enumeration" that increases the value by more than 1, such as: |
A variation of this idea is the "stepped enumeration" that increases the value by more than 1, such as: |
||
< |
<syntaxhighlight lang="forth">: SIZED-ENUM ( n s -<name>- n+s ) OVER CONSTANT + ; |
||
: CELL-ENUM ( n -<name>- n+cell ) CELL SIZED-ENUM ;</ |
: CELL-ENUM ( n -<name>- n+cell ) CELL SIZED-ENUM ;</syntaxhighlight> |
||
A programmer could combine these enum definers in any way desired: |
A programmer could combine these enum definers in any way desired: |
||
< |
<syntaxhighlight lang="forth">0 ENUM FIRST \ value = 0 |
||
CELL-ENUM SECOND \ value = 1 |
CELL-ENUM SECOND \ value = 1 |
||
ENUM THIRD \ value = 5 |
ENUM THIRD \ value = 5 |
||
3 SIZED-ENUM FOURTH \ value = 6 |
3 SIZED-ENUM FOURTH \ value = 6 |
||
ENUM FIFTH \ value = 9 |
ENUM FIFTH \ value = 9 |
||
CONSTANT SIXTH \ value = 10</ |
CONSTANT SIXTH \ value = 10</syntaxhighlight> |
||
Note that a similar technique is often used to implement structures in Forth. |
Note that a similar technique is often used to implement structures in Forth. |
||
For a simple zero-based sequence of constants, one could use a loop in the defining word: |
For a simple zero-based sequence of constants, one could use a loop in the defining word: |
||
< |
<syntaxhighlight lang="forth">: CONSTANTS ( n -- ) 0 DO I CONSTANT LOOP ; |
||
\ resistor digit colors |
\ resistor digit colors |
||
10 CONSTANTS black brown red orange yellow green blue violet gray white</ |
10 CONSTANTS black brown red orange yellow green blue violet gray white</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|2003}} |
{{works with|Fortran|2003}} |
||
< |
<syntaxhighlight lang="fortran">enum, bind(c) |
||
enumerator :: one=1, two, three, four, five |
enumerator :: one=1, two, three, four, five |
||
enumerator :: six, seven, nine=9 |
enumerator :: six, seven, nine=9 |
||
end enum</ |
end enum</syntaxhighlight> |
||
The syntax |
The syntax |
||
< |
<syntaxhighlight lang="fortran">enum, bind(c) :: nametype |
||
enumerator :: one=1, two, three |
enumerator :: one=1, two, three |
||
end enum nametype</ |
end enum nametype</syntaxhighlight> |
||
does not work with gfortran; it is used in some [http://docs.cray.com/books/S-3692-51/html-S-3692-51/z970507905n9123.html Cray docs] about Fortran, but the syntax shown at [http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlf101a.doc/xlflr/enum.htm IBM] is the one gfortran can understand. (Cray's docs refer to Fortran 2003 draft, IBM docs refers to Fortran 2003 standard, but read the brief [http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlf101a.doc/xlflr/languagestandards.htm#wq17 Fortran 2003 Standard] section to understand why differences may exist...) |
does not work with gfortran; it is used in some [http://docs.cray.com/books/S-3692-51/html-S-3692-51/z970507905n9123.html Cray docs] about Fortran, but the syntax shown at [http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlf101a.doc/xlflr/enum.htm IBM] is the one gfortran can understand. (Cray's docs refer to Fortran 2003 draft, IBM docs refers to Fortran 2003 standard, but read the brief [http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlf101a.doc/xlflr/languagestandards.htm#wq17 Fortran 2003 Standard] section to understand why differences may exist...) |
||
=={{header| |
=={{header|Free Pascal}}== |
||
See [[#Delphi|Delphi]]. |
|||
Enumerations in F# always have explicit values: |
|||
Note, depending on the <tt>{$scopedEnum}</tt> compiler switch (as of definition time), enumeration type members are identified via the type name prepended. |
|||
<lang fsharp>type Fruit = |
|||
| Apple = 0 |
|||
| Banana = 1 |
|||
| Cherry = 2 |
|||
Additionally, enumeration types can be passed to <tt>write</tt>/<tt>writeLn</tt> producing the Pascal (source code) identifier. |
|||
let basket = [ Fruit.Apple ; Fruit.Banana ; Fruit.Cherry ] |
|||
Seq.iter (printfn "%A") basket</lang> |
|||
=={{header|FreeBASIC}}== |
|||
If the initialization values are omitted, the resulting type is a discriminated union (algebraic data type) instead. |
|||
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
|||
Simple discriminated unions can be used similarly to enumerations, but they are never convertible from and to integers, and their internal representation is quite different. |
|||
Enum Animals |
|||
<lang fsharp>type Fruit = |
|||
Cat |
|||
Dog |
|||
| Banana |
|||
Zebra |
|||
| Cherry |
|||
End Enum |
|||
let basket = [ Apple ; Banana ; Cherry ] |
|||
Seq.iter (printfn "%A") basket</lang> |
|||
Enum Dogs |
|||
Bulldog = 1 |
|||
Terrier = 2 |
|||
WolfHound = 4 |
|||
End Enum |
|||
Print Cat, Dog, Zebra |
|||
Print Bulldog, Terrier, WolfHound |
|||
Sleep</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0 1 2 |
|||
1 2 4 |
|||
</pre> |
|||
=={{header|FutureBasic}}== |
|||
<syntaxhighlight lang="text">window 1, @"Enumerations", (0,0,480,270) |
|||
begin enum 1 |
|||
_apple |
|||
_banana |
|||
_cherry |
|||
end enum |
|||
begin enum |
|||
_appleExplicit = 10 |
|||
_bananaExplicit = 15 |
|||
_cherryExplicit = 30 |
|||
end enum |
|||
print "_apple = "; _apple |
|||
print "_banana = "; _banana |
|||
print "_cherry = "; _cherry |
|||
print |
|||
print "_appleExplicit = "; _appleExplicit |
|||
print "_bananaExplicit = "; _bananaExplicit |
|||
print "_cherryExplicit = "; _cherryExplicit |
|||
HandleEvents</syntaxhighlight> |
|||
Output |
|||
<pre> |
|||
_apple = 1 |
|||
_banana = 2 |
|||
_cherry = 3 |
|||
_appleExplicit = 10 |
|||
_bananaExplicit = 15 |
|||
_cherryExplicit = 30 |
|||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Go's enumeration-like feature is called iota. It generates sequential integer constants. |
Go's enumeration-like feature is called iota. It generates sequential integer constants. |
||
< |
<syntaxhighlight lang="go">const ( |
||
apple = iota |
apple = iota |
||
banana |
banana |
||
cherry |
cherry |
||
)</ |
)</syntaxhighlight> |
||
The above is equivalent to, |
The above is equivalent to, |
||
< |
<syntaxhighlight lang="go">const ( |
||
apple = 0 |
apple = 0 |
||
banana = 1 |
banana = 1 |
||
cherry = 2 |
cherry = 2 |
||
)</ |
)</syntaxhighlight> |
||
Constants in Go are not typed they way variables are, they are typed when used just like literal constants. |
Constants in Go are not typed they way variables are, they are typed when used just like literal constants. |
||
Here is an example of a type safe enumeration: |
Here is an example of a type safe enumeration: |
||
< |
<syntaxhighlight lang="go">type fruit int |
||
const ( |
const ( |
||
Line 454: | Line 931: | ||
banana |
banana |
||
cherry |
cherry |
||
)</ |
)</syntaxhighlight> |
||
And using explicit values (note each constant must be individual typed here unlike with iota) |
And using explicit values (note each constant must be individual typed here unlike with iota): |
||
< |
<syntaxhighlight lang="go">type fruit int |
||
const ( |
const ( |
||
Line 462: | Line 939: | ||
banana fruit = 1 |
banana fruit = 1 |
||
cherry fruit = 2 |
cherry fruit = 2 |
||
)</ |
)</syntaxhighlight> |
||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
Enumerations: |
Enumerations: |
||
< |
<syntaxhighlight lang="groovy">enum Fruit { apple, banana, cherry } |
||
enum ValuedFruit { |
enum ValuedFruit { |
||
Line 476: | Line 953: | ||
println Fruit.values() |
println Fruit.values() |
||
println ValuedFruit.values()</ |
println ValuedFruit.values()</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre>[apple, banana, cherry] |
<pre>[apple, banana, cherry] |
||
[apple(1), banana(2), cherry(3)]</pre> |
[apple(1), banana(2), cherry(3)]</pre> |
||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">data Fruit = Apple | Banana | Cherry deriving Enum</syntaxhighlight> |
||
=={{header|Huginn}}== |
|||
<syntaxhighlight lang="huginn">enum FRUIT { |
|||
APPLE, |
|||
BANANA, |
|||
CHERRY |
|||
}</syntaxhighlight> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
Nether Icon nor Unicon has an explicit enumeration type; however, there are several approaches that can be used for this purpose: |
|||
<syntaxhighlight lang="icon"> fruits := [ "apple", "banana", "cherry", "apple" ] # a list keeps ordered data |
|||
fruits := set("apple", "banana", "cherry") # a set keeps unique data |
|||
fruits := table() # table keeps an unique data with values |
|||
fruits["apple"] := 1 |
|||
fruits["banana"] := 2 |
|||
fruits["cherry"] := 3</syntaxhighlight> |
|||
=={{header|Inform 7}}== |
=={{header|Inform 7}}== |
||
< |
<syntaxhighlight lang="inform7">Fruit is a kind of value. The fruits are apple, banana, and cherry.</syntaxhighlight> |
||
Inform 7 doesn't have conversions between enumerated values and numbers, but you can assign properties to enumerated values: |
Inform 7 doesn't have conversions between enumerated values and numbers, but you can assign properties to enumerated values: |
||
< |
<syntaxhighlight lang="inform7">[sentence form] |
||
Fruit is a kind of value. The fruits are apple, banana, and cherry. |
Fruit is a kind of value. The fruits are apple, banana, and cherry. |
||
A fruit has a number called numeric value. |
A fruit has a number called numeric value. |
||
The numeric value of apple is 1. |
The numeric value of apple is 1. |
||
The numeric value of banana is 2. |
The numeric value of banana is 2. |
||
The numeric value of cherry is 3.</ |
The numeric value of cherry is 3.</syntaxhighlight> |
||
< |
<syntaxhighlight lang="inform7">[table form] |
||
Fruit is a kind of value. The fruits are defined by the Table of Fruits. |
Fruit is a kind of value. The fruits are defined by the Table of Fruits. |
||
Line 502: | Line 996: | ||
apple 1 |
apple 1 |
||
banana 2 |
banana 2 |
||
cherry 3</ |
cherry 3</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
|||
Nether Icon nor Unicon has an explicit enumeration type; however, there are several approaches that can be used for this purpose: |
|||
<lang Icon> fruits := [ "apple", "banana", "cherry", "apple" ] # a list keeps ordered data |
|||
fruits := set("apple", "banana", "cherry") # a set keeps unique data |
|||
fruits := table() # table keeps an unique data with values |
|||
fruits["apple"] := 1 |
|||
fruits["banana"] := 2 |
|||
fruits["cherry"] := 3</lang> |
|||
=={{header|J}}== |
=={{header|J}}== |
||
J's typing system is fixed, and so extensions occur at the application level. For example, one could create an object |
J's typing system is fixed, and so extensions occur at the application level. For example, one could create an object |
||
< |
<syntaxhighlight lang="j"> enum =: cocreate'' |
||
( (;:'apple banana cherry') ,L:0 '__enum' ) =: i. 3 |
( (;:'apple banana cherry') ,L:0 '__enum' ) =: i. 3 |
||
cherry__enum |
cherry__enum |
||
2</ |
2</syntaxhighlight> |
||
But this is more akin to a "methodless class or object" than an enum in other languages. |
But this is more akin to a "methodless class or object" than an enum in other languages. |
||
That said, note that the "natural way", in J, of dealing with issues treated in other languages through enums is to use an array of names. |
That said, note that the "natural way", in J, of dealing with issues treated in other languages through enums is to use an array of names. |
||
< |
<syntaxhighlight lang="j"> fruit=: ;:'apple banana cherry'</syntaxhighlight> |
||
Now you can get the name associated with an index: |
Now you can get the name associated with an index: |
||
< |
<syntaxhighlight lang="j"> 2 { fruit |
||
+------+ |
+------+ |
||
|cherry| |
|cherry| |
||
+------+</ |
+------+</syntaxhighlight> |
||
And you can get the index associated with a name: |
And you can get the index associated with a name: |
||
< |
<syntaxhighlight lang="j"> fruit i.<'banana' |
||
1</ |
1</syntaxhighlight> |
||
And you can define an arithmetic with the enum for its domain and range. Here, for example, is 2=1+1: |
And you can define an arithmetic with the enum for its domain and range. Here, for example, is 2=1+1: |
||
< |
<syntaxhighlight lang="j"> (<'banana') +&.(fruit&i.) <'banana' |
||
+------+ |
+------+ |
||
|cherry| |
|cherry| |
||
+------+</ |
+------+</syntaxhighlight> |
||
And, you can iterate over the values |
And, you can iterate over the values, along with numerous other variations on these themes.<syntaxhighlight lang="j"> {{for_example. fruit do. echo;example end.}} '' |
||
apple |
|||
banana |
|||
cherry</syntaxhighlight> |
|||
A person could reasonably argue that enums were introduced in some languages to work around deficiencies in array handling in those languages. |
(A person could reasonably argue that enums were introduced in some languages to work around deficiencies in array handling in those languages. But this would be a part of a larger discussion about type systems and the use of systems of bit patterns to represent information.) |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|Java|1.5+}} |
{{works with|Java|1.5+}} |
||
< |
<syntaxhighlight lang="java5">enum Fruits{ |
||
APPLE, BANANA, CHERRY |
APPLE, BANANA, CHERRY |
||
}</ |
}</syntaxhighlight> |
||
Or: |
Or: |
||
< |
<syntaxhighlight lang="java5">enum Fruits{ |
||
APPLE(0), BANANA(1), CHERRY(2) |
APPLE(0), BANANA(1), CHERRY(2) |
||
private final int value; |
private final int value; |
||
fruits(int value) { this.value = value; } |
fruits(int value) { this.value = value; } |
||
public int value() { return value; } |
public int value() { return value; } |
||
}</ |
}</syntaxhighlight> |
||
Conventionally, enums have the same case rules as classes, while enum values are in all caps (like other constants). All cases are allowed for both names, though, as long as they don't conflict with other classes in the same package. |
Conventionally, enums have the same case rules as classes, while enum values are in all caps (like other constants). All cases are allowed for both names, though, as long as they don't conflict with other classes in the same package. |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
In javascript, usually used for this a strings. |
|||
var fruits = { APPLE : 0, BANANA : 1, CHERRY : 2 }; |
|||
Object.freeze(fruits); |
|||
</lang> |
|||
Object.freeze() Prevents modification of the enumeration at run-time. |
|||
<syntaxhighlight lang="javascript"> |
|||
=={{header|JSON}}== |
|||
// enum fruits { apple, banana, cherry } |
|||
{"fruits" : { "apple" : 0, "banana" : 1, "cherry" : 2 }</lang> |
|||
var f = "apple"; |
|||
if(f == "apple"){ |
|||
f = "banana"; |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
Finite, ordered enumerations can be represented in jq as JSON arrays, e.g. ["apple", "banana", "cherry"], or as sequences, |
|||
e.g. ("apple", "banana", "cherry"). The latter interpretation corresponds to the idea of '''enumerating''' a collection, and also dovetails with the concept of infinite enumerations. |
|||
Countably-infinite ordered enumerations can be represented by generators, e.g. the non-negative natural numbers can be represented by the jq expression: |
|||
1 | while(true; .+1) |
|||
Finite, unordered enumerations can be represented as JSON objects, as in the JSON section of this article. |
|||
In this context, it is worth noting that jq allows a shorthand notation for specifying objects, so that we can for example write: |
|||
def fruits: {apple, banana, cherry}; # i.e. {"apple" : null, "banana": null, "cherry": null } |
|||
=={{header|JScript.NET}}== |
=={{header|JScript.NET}}== |
||
< |
<syntaxhighlight lang="jscript">enum fruits { apple, banana, cherry } |
||
enum fruits { apple = 0, banana = 1, cherry = 2 }</ |
enum fruits { apple = 0, banana = 1, cherry = 2 }</syntaxhighlight> |
||
=={{header| |
=={{header|JSON}}== |
||
<syntaxhighlight lang="json">{"fruits" : { "apple" : null, "banana" : null, "cherry" : null } |
|||
{"fruits" : { "apple" : 0, "banana" : 1, "cherry" : 2 }</syntaxhighlight> |
|||
=={{header|Julia}}== |
|||
<syntaxhighlight lang="julia"> |
|||
@enum Fruits APPLE BANANA CHERRY |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
julia> Fruits |
|||
Enum Fruits: |
|||
APPLE = 0 |
|||
BANANA = 1 |
|||
CHERRY = 2 |
|||
</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight lang="scala">// version 1.0.5-2 |
|||
enum class Animals { |
|||
CAT, DOG, ZEBRA |
|||
} |
|||
enum class Dogs(val id: Int) { |
|||
BULLDOG(1), TERRIER(2), WOLFHOUND(4) |
|||
} |
|||
fun main(args: Array<String>) { |
|||
for (value in Animals.values()) println("${value.name.padEnd(5)} : ${value.ordinal}") |
|||
println() |
|||
for (value in Dogs.values()) println("${value.name.padEnd(9)} : ${value.id}") |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
CAT : 0 |
|||
DOG : 1 |
|||
ZEBRA : 2 |
|||
BULLDOG : 1 |
|||
TERRIER : 2 |
|||
WOLFHOUND : 4 |
|||
</pre> |
|||
=={{header|Lingo}}== |
|||
Lingo neither knows the concept of enumerations nor of constants. But an enumeration-like hash (property list) that is immutable concerning standard list methods and operators can be created by sub-classing a property list and overwriting list/property list access methods (which also overwrites bracket access operators on the fly): |
|||
<syntaxhighlight lang="lingo">-- parent script "Enumeration" |
|||
property ancestor |
|||
on new (me) |
|||
data = [:] |
|||
repeat with i = 2 to the paramCount |
|||
data[param(i)] = i-1 |
|||
end repeat |
|||
me.ancestor = data |
|||
return me |
|||
end |
|||
on setAt (me) |
|||
-- do nothing |
|||
end |
|||
on setProp (me) |
|||
-- do nothing |
|||
end |
|||
on deleteAt (me) |
|||
-- do nothing |
|||
end |
|||
on deleteProp (me) |
|||
-- do nothing |
|||
end |
|||
on addProp (me) |
|||
-- do nothing |
|||
end</syntaxhighlight> |
|||
<syntaxhighlight lang="lingo">enumeration = script("Enumeration").new("APPLE", "BANANA", "CHERRY") |
|||
put enumeration["BANANA"] |
|||
-- 2 |
|||
-- try to change a value after construction (fails) |
|||
enumeration["BANANA"] = 666 |
|||
put enumeration["BANANA"] |
|||
-- 2 |
|||
-- try to change a value after construction using setProp (fails) |
|||
enumeration.setProp("BANANA", 666) |
|||
put enumeration["BANANA"] |
|||
-- 2 |
|||
-- try to delete a value after construction (fails) |
|||
enumeration.deleteAt(2) |
|||
put enumeration["BANANA"] |
|||
-- 2 |
|||
-- try to delete a value after construction using deleteProp (fails) |
|||
enumeration.deleteProp("BANANA") |
|||
put enumeration["BANANA"] |
|||
-- 2 |
|||
-- try to add a new value after construction (fails) |
|||
enumeration["FOO"] = 666 |
|||
put enumeration["FOO"] |
|||
-- <Void> |
|||
-- try to add a new value after construction using addProp (fails) |
|||
enumeration.addProp("FOO", 666) |
|||
put enumeration["FOO"] |
|||
-- <Void></syntaxhighlight> |
|||
=={{header|Lua}}== |
|||
An explicit enum can be formed by mapping strings to numbers |
An explicit enum can be formed by mapping strings to numbers |
||
< |
<syntaxhighlight lang="lua"> |
||
local fruit = {apple = 0, banana = 1, cherry = 2} |
local fruit = {apple = 0, banana = 1, cherry = 2} |
||
</syntaxhighlight> |
|||
</lang> |
|||
or simply by local variables. |
or simply by local variables. |
||
< |
<syntaxhighlight lang="lua"> |
||
local apple, banana, cherry = 0,1,2 |
local apple, banana, cherry = 0,1,2 |
||
</syntaxhighlight> |
|||
</lang> |
|||
Although since Lua strings are interned, there is as much benefit to simply using strings. |
Although since Lua strings are interned, there is as much benefit to simply using strings. |
||
=={{header|M2000 Interpreter}}== |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module Checkit { |
|||
\\ need revision 15, version 9.4 |
|||
Enum Fruit {apple, banana, cherry} |
|||
Enum Fruit2 {apple2=10, banana2=20, cherry2=30} |
|||
Print apple, banana, cherry |
|||
Print apple2, banana2, cherry2 |
|||
Print Len(apple)=0 |
|||
Print Len(banana)=1 |
|||
Print Len(cherry)=2 |
|||
Print Len(cherry2)=2, Cherry2=30, Type$(Cherry2)="Fruit2" |
|||
k=each(Fruit) |
|||
While k { |
|||
\\ name of variable, value, length from first (0, 1, 2) |
|||
Print Eval$(k), Eval(k), k^ |
|||
} |
|||
m=apple |
|||
Print Eval$(m)="apple" |
|||
Print Eval(m)=m |
|||
m++ |
|||
Print Eval$(m)="banana" |
|||
Try { |
|||
\\ error, m is an object |
|||
m=100 |
|||
} |
|||
Try { |
|||
\\ error not the same type |
|||
m=apple2 |
|||
} |
|||
Try { |
|||
\\ read only can't change |
|||
apple2++ |
|||
} |
|||
m++ |
|||
Print Eval$(m)="cherry", m |
|||
k=Each(Fruit2 end to start) |
|||
While k { |
|||
Print Eval$(k), Eval(k) , k^ |
|||
CheckByValue(Eval(k)) |
|||
} |
|||
m2=apple2 |
|||
Print "-------------------------" |
|||
CheckByValue(m2) |
|||
CheckByReference(&m2) |
|||
Print m2 |
|||
Sub CheckByValue(z as Fruit2) |
|||
Print Eval$(z), z |
|||
End Sub |
|||
Sub CheckByReference(&z as Fruit2) |
|||
z++ |
|||
Print Eval$(z), z |
|||
End Sub |
|||
} |
|||
Checkit |
|||
</syntaxhighlight> |
|||
=={{header|M4}}== |
=={{header|M4}}== |
||
< |
<syntaxhighlight lang="m4">define(`enums', |
||
`define(`$2',$1)`'ifelse(eval($#>2),1,`enums(incr($1),shift(shift($@)))')') |
`define(`$2',$1)`'ifelse(eval($#>2),1,`enums(incr($1),shift(shift($@)))')') |
||
define(`enum', |
define(`enum', |
||
`enums(1,$@)') |
`enums(1,$@)') |
||
enum(a,b,c,d) |
enum(a,b,c,d) |
||
`c='c</ |
`c='c</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
c=3 |
c=3 |
||
</pre> |
</pre> |
||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
=={{header|Mathematica}}== |
|||
Enumerations are not very useful in a symbolic language like Mathematica. If desired, an 'enum' function could be defined : |
Enumerations are not very useful in a symbolic language like Mathematica. If desired, an 'enum' function could be defined : |
||
< |
<syntaxhighlight lang="mathematica">MapIndexed[Set, {A, B, F, G}] |
||
->{{1}, {2}, {3}, {4}} |
->{{1}, {2}, {3}, {4}} |
||
Line 621: | Line 1,300: | ||
G |
G |
||
->{4}</ |
->{4}</syntaxhighlight> |
||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
Enumeration is done by creating a cell array (a.k.a set) of objects, where the numeral of the object is its index in the 1-based cell array. The cell array structure can contain any type of data structure including other cell arrays, and all members don't have to be the same data type. |
Enumeration is done by creating a cell array (a.k.a set) of objects, where the numeral of the object is its index in the 1-based cell array. The cell array structure can contain any type of data structure including other cell arrays, and all members don't have to be the same data type. |
||
Example: |
Example: |
||
< |
<syntaxhighlight lang="matlab">stuff = {'apple', [1 2 3], 'cherry',1+2i} |
||
stuff = |
stuff = |
||
'apple' [1x3 double] 'cherry' [1.000000000000000 + 2.000000000000000i]</ |
'apple' [1x3 double] 'cherry' [1.000000000000000 + 2.000000000000000i]</syntaxhighlight> |
||
=={{header|Metafont}}== |
=={{header|Metafont}}== |
||
Metafont has no an enumeration type. However we can define an useful macro to simulate an enumeration. E.g. |
Metafont has no an enumeration type. However we can define an useful macro to simulate an enumeration. E.g. |
||
< |
<syntaxhighlight lang="metafont">vardef enum(expr first)(text t) = |
||
save ?; ? := first; |
save ?; ? := first; |
||
forsuffixes e := t: e := ?; ?:=?+1; endfor |
forsuffixes e := t: e := ?; ?:=?+1; endfor |
||
enddef;</ |
enddef;</syntaxhighlight> |
||
Usage example: |
Usage example: |
||
< |
<syntaxhighlight lang="metafont">enum(1, Apple, Banana, Cherry); |
||
enum(5, Orange, Pineapple, Qfruit); |
enum(5, Orange, Pineapple, Qfruit); |
||
show Apple, Banana, Cherry, Orange, Pineapple, Qfruit; |
show Apple, Banana, Cherry, Orange, Pineapple, Qfruit; |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Modula-3}}== |
=={{header|Modula-3}}== |
||
< |
<syntaxhighlight lang="modula3">TYPE Fruit = {Apple, Banana, Cherry};</syntaxhighlight> |
||
The values are accessed by qualifying their names. |
The values are accessed by qualifying their names. |
||
< |
<syntaxhighlight lang="modula3">fruit := Fruit.Apple;</syntaxhighlight> |
||
You can get an element's position in the enumeration by using <code>ORD</code> and get the element given the position by using <code>VAL</code>. |
You can get an element's position in the enumeration by using <code>ORD</code> and get the element given the position by using <code>VAL</code>. |
||
< |
<syntaxhighlight lang="modula3">ORD(Fruit.Apple); (* Returns 0 *) |
||
VAL(0, Fruit); (* Returns Fruit.Apple *)</ |
VAL(0, Fruit); (* Returns Fruit.Apple *)</syntaxhighlight> |
||
=={{header|Nemerle}}== |
=={{header|Nemerle}}== |
||
< |
<syntaxhighlight lang="nemerle">enum Fruit { |
||
|apple |
|apple |
||
|banana |
|banana |
||
Line 669: | Line 1,347: | ||
|summer = 3 |
|summer = 3 |
||
|autumn = 4 |
|autumn = 4 |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Nim}}== |
|||
<syntaxhighlight lang="nim"># Simple declaration. |
|||
type Fruits1 = enum aApple, aBanana, aCherry |
|||
# Specifying values (accessible using "ord"). |
|||
type Fruits2 = enum bApple = 0, bBanana = 2, bCherry = 5 |
|||
# Enumerations with a scope which prevent name conflict. |
|||
type Fruits3 {.pure.} = enum Apple, Banana, Cherry |
|||
type Fruits4 {.pure.} = enum Apple = 3, Banana = 8, Cherry = 10 |
|||
var x = Fruits3.Apple # Need to qualify as there are several possible "Apple". |
|||
# Using vertical presentation and specifying string representation. |
|||
=={{header|Nimrod}}== |
|||
type Fruits5 = enum |
|||
cApple = "Apple" |
|||
cBanana = "Banana" |
|||
cCherry = "Cherry" |
|||
echo cApple # Will display "Apple". |
|||
# Specifying values and/or string representation. |
|||
type Fruits = enum Apple = 0, Banana = 1, Cherry = 2</lang> |
|||
type Fruits6 = enum |
|||
Apple = (1, "apple") |
|||
Banana = 3 # implicit name is "Banana". |
|||
Cherry = "cherry" # implicit value is 4.</syntaxhighlight> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang="objeck"> |
||
enum Color := -3 { |
enum Color := -3 { |
||
Red, |
Red, |
||
Line 689: | Line 1,387: | ||
Terrier |
Terrier |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objective-C}}== |
|||
With iOS 6+ SDK / Mac OS X 10.8+ SDK: |
|||
<syntaxhighlight lang="objc">typedef NS_ENUM(NSInteger, fruits) { apple, banana, cherry }; |
|||
typedef NS_ENUM(NSInteger, fruits) { apple = 0, banana = 1, cherry = 2 };</syntaxhighlight> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml">type fruit = |
||
| Apple |
| Apple |
||
| Banana |
| Banana |
||
| Cherry</ |
| Cherry</syntaxhighlight> |
||
=={{header|Odin}}== |
|||
<syntaxhighlight lang="odin">package main |
|||
Fruit :: enum { |
|||
Apple, |
|||
Banana, |
|||
Cherry, |
|||
} |
|||
FruitWithNumber :: enum { |
|||
Strawberry = 0, |
|||
Pear = 27, |
|||
} |
|||
main :: proc() { |
|||
b := Fruit.Banana |
|||
assert(int(b) == 1) // Enums always have implicit values |
|||
p := FruitWithNumber.Pear |
|||
assert(int(p) == 27) |
|||
}</syntaxhighlight> |
|||
=={{header|Oforth}}== |
|||
In Oforth, you use symbols to define enumerations.Symbols are strings that are identical : if two symbols are equal (==), they are the same object. |
|||
You can't define explicit values for these symbols as they a themseelves values. |
|||
Symbols begin with $. If the symbol does not exists yet, it is created. |
|||
<syntaxhighlight lang="oforth">[ $apple, $banana, $cherry ] const: Fruits</syntaxhighlight> |
|||
=={{header|Ol}}== |
|||
Ol enumerations is an builtin "ff"s as a simple fast dictionaries with number, constant or symbol keys and any typed values. |
|||
<syntaxhighlight lang="scheme"> |
|||
(define fruits '{ |
|||
apple 0 |
|||
banana 1 |
|||
cherry 2}) |
|||
; or |
|||
(define fruits { |
|||
'apple 0 |
|||
'banana 1 |
|||
'cherry 2}) |
|||
; getting enumeration value: |
|||
(print (get fruits 'apple -1)) ; ==> 0 |
|||
; or simply |
|||
(print (fruits 'apple)) ; ==> 0 |
|||
; or simply with default (for non existent enumeration key) value |
|||
(print (fruits 'carrot -1)) ; ==> -1 |
|||
; simple function to create enumeration with autoassigning values |
|||
(define (make-enumeration . args) |
|||
(fold (lambda (ff arg i) |
|||
(put ff arg i)) |
|||
#empty |
|||
args |
|||
(iota (length args)))) |
|||
(print (make-enumeration 'apple 'banana 'cherry)) |
|||
; ==> '#ff((apple . 0) (banana . 1) (cherry . 2)) |
|||
</syntaxhighlight> |
|||
=={{header|OxygenBasic}}== |
|||
<syntaxhighlight lang="text"> |
|||
enum fruits |
|||
apple |
|||
pear |
|||
orange = 14 |
|||
banana |
|||
mango |
|||
end enum |
|||
print banana '15 |
|||
'fruits values: |
|||
' apple 0 |
|||
' pear 1 |
|||
' orange 14 |
|||
' banana 15 |
|||
' mango 16 |
|||
</syntaxhighlight> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Most of the time you will just use atoms where you would use enums in C. Atoms start with a lower-case letter and are just symbols that evaluate to themselves. For example: |
Most of the time you will just use atoms where you would use enums in C. Atoms start with a lower-case letter and are just symbols that evaluate to themselves. For example: |
||
< |
<syntaxhighlight lang="oz">declare |
||
fun {IsFruit A} |
fun {IsFruit A} |
||
{Member A [apple banana cherry]} |
{Member A [apple banana cherry]} |
||
end |
end |
||
in |
in |
||
{Show {IsFruit banana}}</ |
{Show {IsFruit banana}}</syntaxhighlight> |
||
If you need constants with increasing values, you could just enumerate them manually: |
If you need constants with increasing values, you could just enumerate them manually: |
||
< |
<syntaxhighlight lang="oz">declare |
||
Apple = 1 |
Apple = 1 |
||
Banana = 2 |
Banana = 2 |
||
Cherry = 3</ |
Cherry = 3</syntaxhighlight> |
||
Or you could write a procedure that does the job automatically: |
Or you could write a procedure that does the job automatically: |
||
< |
<syntaxhighlight lang="oz">declare |
||
proc {Enumeration Xs} |
proc {Enumeration Xs} |
||
Xs = {List.number 1 {Length Xs} 1} |
Xs = {List.number 1 {Length Xs} 1} |
||
Line 720: | Line 1,511: | ||
[Apple Banana Cherry] = {Enumeration} |
[Apple Banana Cherry] = {Enumeration} |
||
in |
in |
||
{Show Cherry}</ |
{Show Cherry}</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
Standard Pascal as per ISO 7185 only allows contiguous lists of identifiers as enumerated type definitions. |
|||
See [[Enumerations#Delphi | Delphi]] |
|||
An explicit index may not be specified, but [[#Delphi|Delphi]] and [[#Free Pascal|Free Pascal]] allow this. |
|||
However, it is guaranteed, that the <tt>ord</tt>inal value will correspond to the member’s position in the list (<tt>0</tt>-based). |
|||
<syntaxhighlight lang="pascal">type |
|||
phase = (red, green, blue);</syntaxhighlight> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl"># Using an array |
||
my @fruits = qw(apple banana cherry); |
my @fruits = qw(apple banana cherry); |
||
# Using a hash |
# Using a hash |
||
my %fruits = ( apple => 0, banana => 1, cherry => 2 );</ |
my %fruits = ( apple => 0, banana => 1, cherry => 2 );</syntaxhighlight> |
||
=={{header| |
=={{header|Phix}}== |
||
{{libheader|Phix/basics}} |
|||
{{works with|Rakudo|#21 "Seattle"}} |
|||
<!--<syntaxhighlight lang="phix">--> |
|||
<span style="color: #008080;">enum</span> <span style="color: #000000;">apple<span style="color: #0000FF;">,</span> <span style="color: #000000;">banana<span style="color: #0000FF;">,</span> <span style="color: #000000;">orange</span> |
|||
<lang perl6>enum Fruit <Apple Banana Cherry>; # Numbered 0 through 2. |
|||
<span style="color: #008080;">enum</span> <span style="color: #000000;">apple<span style="color: #0000FF;">=<span style="color: #000000;">5<span style="color: #0000FF;">,</span> <span style="color: #000000;">banana<span style="color: #0000FF;">=<span style="color: #000000;">10<span style="color: #0000FF;">,</span> <span style="color: #000000;">orange<span style="color: #0000FF;">= |
|||
<!--</syntaxhighlight>--> |
|||
enum ClassicalElement ( |
|||
Earth => 5, |
|||
'Air', # Gets the value 6. |
|||
Fire => 'hot', |
|||
Water => 'wet' |
|||
);</lang> |
|||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
< |
<syntaxhighlight lang="php">// Using an array/hash |
||
$fruits = array( "apple", "banana", "cherry" ); |
$fruits = array( "apple", "banana", "cherry" ); |
||
$fruits = array( "apple" => 0, "banana" => 1, "cherry" => 2 ); |
$fruits = array( "apple" => 0, "banana" => 1, "cherry" => 2 ); |
||
Line 762: | Line 1,552: | ||
define("FRUIT_APPLE", 0); |
define("FRUIT_APPLE", 0); |
||
define("FRUIT_BANANA", 1); |
define("FRUIT_BANANA", 1); |
||
define("FRUIT_CHERRY", 2);</ |
define("FRUIT_CHERRY", 2);</syntaxhighlight> |
||
=={{header|Picat}}== |
|||
{{trans|Prolog}} |
|||
Picat doesn't have enumerations but they can be simulated by facts. |
|||
<syntaxhighlight lang="picat">fruit(apple,1). |
|||
fruit(banana,2). |
|||
fruit(cherry,4). |
|||
print_fruit_name(N) :- |
|||
fruit(Name,N), |
|||
printf("It is %w\nn", Name).</syntaxhighlight> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Enumerations are not very useful in a symbolic language like PicoLisp. If |
Enumerations are not very useful in a symbolic language like PicoLisp. If |
||
desired, an 'enum' function could be defined: |
desired, an 'enum' function could be defined: |
||
< |
<syntaxhighlight lang="picolisp">(de enum "Args" |
||
(mapc def "Args" (range 1 (length "Args"))) )</ |
(mapc def "Args" (range 1 (length "Args"))) )</syntaxhighlight> |
||
And used in this way: |
And used in this way: |
||
< |
<syntaxhighlight lang="picolisp">: (enum A B C D E F) |
||
-> F</ |
-> F</syntaxhighlight> |
||
<pre>: A |
<pre>: A |
||
-> 1 |
-> 1 |
||
Line 780: | Line 1,583: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
define ordinal animal (frog, gnu, elephant, snake); |
define ordinal animal (frog, gnu, elephant, snake); |
||
define ordinal color (red value (1), green value (3), blue value (5)); |
define ordinal color (red value (1), green value (3), blue value (5)); |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|PowerShell}}== |
|||
Without explicit values. |
|||
{{works with|PowerShell|5}} |
|||
<syntaxhighlight lang="powershell"> |
|||
Enum fruits { |
|||
Apple |
|||
Banana |
|||
Cherry |
|||
} |
|||
[fruits]::Apple |
|||
[fruits]::Apple + 1 |
|||
[fruits]::Banana + 1 |
|||
</syntaxhighlight> |
|||
<b>Output:</b> |
|||
<pre> |
|||
Apple |
|||
Banana |
|||
Cherry |
|||
</pre> |
|||
With explicit values. |
|||
{{works with|PowerShell|5}} |
|||
<syntaxhighlight lang="powershell"> |
|||
Enum fruits { |
|||
Apple = 10 |
|||
Banana = 15 |
|||
Cherry = 30 |
|||
} |
|||
[fruits]::Apple |
|||
[fruits]::Apple + 1 |
|||
[fruits]::Banana + 1 |
|||
</syntaxhighlight> |
|||
<pre> |
|||
Apple |
|||
11 |
|||
16 |
|||
</pre> |
|||
=={{header|Prolog}}== |
|||
Prolog doesn't have enums, but they can be simulated using a set of facts. |
|||
<syntaxhighlight lang="prolog">fruit(apple,1). |
|||
fruit(banana,2). |
|||
fruit(cherry,4). |
|||
write_fruit_name(N) :- |
|||
fruit(Name,N), |
|||
format('It is a ~p~n', Name).</syntaxhighlight> |
|||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
Basic Enumeration is defined as |
Basic Enumeration is defined as |
||
< |
<syntaxhighlight lang="purebasic">Enumeration |
||
#Apple |
#Apple |
||
#Banana |
#Banana |
||
#Cherry |
#Cherry |
||
EndEnumeration</ |
EndEnumeration</syntaxhighlight> |
||
This can also be adjusted to the form |
This can also be adjusted to the form |
||
< |
<syntaxhighlight lang="purebasic">Enumeration 10200 Step 12 |
||
#Constant1 ; 10200 |
#Constant1 ; 10200 |
||
#Constant2 ; 10212 |
#Constant2 ; 10212 |
||
Line 800: | Line 1,651: | ||
#Constant4 = 10117 ; 10117 |
#Constant4 = 10117 ; 10117 |
||
#Constant5 ; 10229 |
#Constant5 ; 10229 |
||
EndEnumeration</ |
EndEnumeration</syntaxhighlight> |
||
The system constant "#PB_Compiler_EnumerationValue" holds last defined value and can be used to chain to a previously started series. |
The system constant "#PB_Compiler_EnumerationValue" holds last defined value and can be used to chain to a previously started series. |
||
E.g. in combination with the code above; |
E.g. in combination with the code above; |
||
< |
<syntaxhighlight lang="purebasic">Enumeration #PB_Compiler_EnumerationValue |
||
#Constant_A ; 10241 |
#Constant_A ; 10241 |
||
#Constant_B ; 10242 |
#Constant_B ; 10242 |
||
EndEnumeration</ |
EndEnumeration</syntaxhighlight> |
||
Enumeration groups can also be named to allow continuation where a previous named group left off. |
|||
<syntaxhighlight lang="purebasic">;This starts the enumeration of a named group 'NamedGroup'. |
|||
Enumeration NamedGroup 5 |
|||
#Green ; 5 |
|||
#Orange ; 6 |
|||
EndEnumeration |
|||
;EnumerationBinary will use values that are a double of the previous value (or starting value). |
|||
EnumerationBinary |
|||
#North ; 1 |
|||
#West ; 2 |
|||
#South ; 4 |
|||
#East ; 8 |
|||
EndEnumeration |
|||
;This continues the enumeration of the previously named group 'NamedGroup'. |
|||
Enumeration NamedGroup |
|||
#Yellow ; 7 |
|||
#Red ; 8 |
|||
EndEnumeration</syntaxhighlight> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
===Python: Version 3.4+=== |
|||
Note: [http://www.python.org/dev/peps/pep-0435/ enumerations have come to Python version 3.4]. |
|||
<syntaxhighlight lang="python">>>> from enum import Enum |
|||
>>> Contact = Enum('Contact', 'FIRST_NAME, LAST_NAME, PHONE') |
|||
>>> Contact.__members__ |
|||
mappingproxy(OrderedDict([('FIRST_NAME', <Contact.FIRST_NAME: 1>), ('LAST_NAME', <Contact.LAST_NAME: 2>), ('PHONE', <Contact.PHONE: 3>)])) |
|||
>>> |
|||
>>> # Explicit |
|||
>>> class Contact2(Enum): |
|||
FIRST_NAME = 1 |
|||
LAST_NAME = 2 |
|||
PHONE = 3 |
|||
>>> Contact2.__members__ |
|||
mappingproxy(OrderedDict([('FIRST_NAME', <Contact2.FIRST_NAME: 1>), ('LAST_NAME', <Contact2.LAST_NAME: 2>), ('PHONE', <Contact2.PHONE: 3>)])) |
|||
>>> </syntaxhighlight> |
|||
===Python: Pre version 3.4=== |
|||
{{works with|Python|2.5}} |
{{works with|Python|2.5}} |
||
There is no special syntax, typically global variables are used with range: |
There is no special syntax, typically global variables are used with range: |
||
< |
<syntaxhighlight lang="python">FIRST_NAME, LAST_NAME, PHONE = range(3)</syntaxhighlight> |
||
Alternately, the above variables can be enumerated from a list with no predetermined length. |
Alternately, the above variables can be enumerated from a list with no predetermined length. |
||
< |
<syntaxhighlight lang="python">vars().update((key,val) for val,key in enumerate(("FIRST_NAME","LAST_NAME","PHONE")))</syntaxhighlight> |
||
;Note that [http://www.python.org/dev/peps/pep-0435/ enumerations are coming to Python version 3.4]. |
|||
=={{header|R}}== |
=={{header|R}}== |
||
R does not have an enumeration type, though factors provide a similar functionality. |
R does not have an enumeration type, though factors provide a similar functionality. |
||
< |
<syntaxhighlight lang="r"> factor(c("apple", "banana", "cherry")) |
||
# [1] apple banana cherry |
# [1] apple banana cherry |
||
# Levels: apple banana cherry</ |
# Levels: apple banana cherry</syntaxhighlight> |
||
[http://tolstoy.newcastle.edu.au/R/help/04/07/0368.html This thread] in the R mail archive contains code for an enum-like class for traffic light colours. |
[http://tolstoy.newcastle.edu.au/R/help/04/07/0368.html This thread] in the R mail archive contains code for an enum-like class for traffic light colours. |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
<syntaxhighlight lang="racket"> |
|||
<lang Racket> |
|||
#lang racket |
#lang racket |
||
Line 869: | Line 1,759: | ||
((ctype-c->scheme _fruits) 4) ; -> '(CHERRY) |
((ctype-c->scheme _fruits) 4) ; -> '(CHERRY) |
||
((ctype-c->scheme _fruits) 5) ; -> '(APPLE CHERRY) |
((ctype-c->scheme _fruits) 5) ; -> '(APPLE CHERRY) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{works with|Rakudo|2016.01}} |
|||
<syntaxhighlight lang="raku" line>enum Fruit <Apple Banana Cherry>; # Numbered 0 through 2. |
|||
enum ClassicalElement ( |
|||
Earth => 5, |
|||
'Air', # gets the value 6 |
|||
'Fire', # gets the value 7 |
|||
Water => 10, |
|||
);</syntaxhighlight> |
|||
=={{header|Raven}}== |
=={{header|Raven}}== |
||
< |
<syntaxhighlight lang="raven">{ 'apple' 0 'banana' 1 'cherry' 2 } as fruits</syntaxhighlight> |
||
=={{header|Retro}}== |
=={{header|Retro}}== |
||
Retro has a library named '''enum'''' for creation of enumerated values. |
Retro has a library named '''enum'''' for creation of enumerated values. |
||
<syntaxhighlight lang="retro">'/examples/enum.retro include |
|||
<lang Retro>needs enum' |
|||
( Creating a series of values ) |
|||
0 ^enum'enum| a b c d | |
|||
( Create values individually ) |
|||
0 ^enum'enum a ^enum'enum b</lang> |
|||
{ 'a=10 'b 'c 'd=998 'e 'f } a:enum |
|||
The actual values for each subsequent enumerated value created are determined by the '''^enum'step''' function. This defaults to incrementing by 1, but can be altered as desired: |
|||
</syntaxhighlight> |
|||
<lang Retro>with enum' |
|||
[ 10 * ] is step |
|||
0 ^enum'enum| a b c d |</lang> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 895: | Line 1,790: | ||
<br>This REXX entry was kinda modeled after the '''BASIC''', '''Forth''', and |
<br>This REXX entry was kinda modeled after the '''BASIC''', '''Forth''', and |
||
'''VBA''' [which does its own enumeration, as does REXX below (as an inventory count)]. |
'''VBA''' [which does its own enumeration, as does REXX below (as an inventory count)]. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program illustrates a method of enumeration of constants via stemmed arrays. */ |
||
fruit.=0 |
fruit.=0 /*the default for all possible "FRUITS." (zero). */ |
||
fruit.apple |
fruit.apple = 65 |
||
fruit.cherry |
fruit.cherry = 4 |
||
fruit.kiwi |
fruit.kiwi = 12 |
||
fruit.peach |
fruit.peach = 48 |
||
fruit.plum |
fruit.plum = 50 |
||
fruit.raspberry |
fruit.raspberry = 17 |
||
fruit.tomato |
fruit.tomato = 8000 |
||
fruit.ugli |
fruit.ugli = 2 |
||
fruit.watermelon = 0.5 /*◄─────────── could also be specified as: 1/2 */ |
|||
/*A |
/*A method of using a list (of some fruits).*/ |
||
@fruits= 'apple apricot avocado banana bilberry blackberry blackcurrant blueberry baobab', |
|||
/* [↓] This is one method of using a list. */ |
|||
'boysenberry breadfruit cantaloupe cherry chilli chokecherry citron coconut', |
|||
'cranberry cucumber currant date dragonfruit durian eggplant elderberry fig', |
|||
'feijoa gac gooseberry grape grapefruit guava honeydew huckleberry jackfruit', |
|||
'jambul juneberry kiwi kumquat lemon lime lingenberry loquat lychee mandarine mango mangosteen netarine orange papaya passionfruit peach pear persimmon', |
|||
'jambul juneberry kiwi kumquat lemon lime lingenberry loquat lychee mandarin', |
|||
'physalis pineapple pitaya pomegranate pomelo plum pumpkin rambutan raspberry redcurrent satsuma squash strawberry tangerine tomato ugli watermelon zucchini' |
|||
'mango mangosteen nectarine orange papaya passionfruit peach pear persimmon', |
|||
/*┌────────────────────────────────────────────────────────────────────┐ |
|||
'physalis pineapple pitaya pomegranate pomelo plum pumpkin rambutan raspberry', |
|||
│ Spoiler alert: sex is discussed below: PG-13. Most berries don't │ |
|||
'redcurrant satsuma squash strawberry tangerine tomato ugli watermelon zucchini' |
|||
│ have "berry" in their name. A berry is a simple fruit produced │ |
|||
│ from a single ovary. Some true berries are: pomegranate, guava, │ |
|||
/*╔════════════════════════════════════════════════════════════════════════════════════╗ |
|||
│ eggplant, tomato, chilli, pumpkin, cucumber, melon, and citruses. │ |
|||
║Parental warning: sex is discussed below: PG─13. Most berries don't have "berry" in║ |
|||
│ Blueberry is a false berry, blackberry is an aggregate fruit, │ |
|||
║their name. A berry is a simple fruit produced from a single ovary. Some true ║ |
|||
║berries are: pomegranate, guava, eggplant, tomato, chilli, pumpkin, cucumber, melon,║ |
|||
│ The following aren't true nuts: almond, cashew, coconut, │ |
|||
║and citruses. Blueberry is a false berry; blackberry is an aggregate fruit; ║ |
|||
│ macadamia, peanut, pecan, pistachio, and walnut. │ |
|||
║and strawberry is an accessory fruit. Most nuts are fruits. The following aren't║ |
|||
└────────────────────────────────────────────────────────────────────┘*/ |
|||
║true nuts: almond, cashew, coconut, macadamia, peanut, pecan, pistachio, and walnut.║ |
|||
/* [↓] due to a Central America blight in 1922.*/ |
|||
╚════════════════════════════════════════════════════════════════════════════════════╝*/ |
|||
if fruit.banana=0 then say "Yes! We have no bananas today." /*(sic)*/ |
|||
if fruit.kiwi \=0 then say "We gots" fruit.kiwi "hairy fruit." /*(sic)*/ |
|||
/* ┌─◄── due to a Central America blight in 1922; it was*/ |
|||
if fruit.peach\=0 then say "We gots" fruit.peach "fuzzy fruit." /*(sic)*/ |
|||
/* ↓ called the Panama disease (a soil─borne fungus)*/ |
|||
maxL = length(' fruit ') |
|||
if fruit.banana=0 then say "Yes! We have no bananas today." /* (sic) */ |
|||
maxQ = length(' quantity ') |
|||
if fruit.kiwi \=0 then say "We gots " fruit.kiwi ' hairy fruit.' /* " */ |
|||
if fruit.peach\=0 then say "We gots " fruit.peach ' fuzzy fruit.' /* " */ |
|||
maxL=length(' fruit ') /*ensure this header title can be shown*/ |
|||
maxQ=length(' quantity ') /* " " " " " " " */ |
|||
say |
say |
||
do |
do p =0 for 2 /*the first pass finds the maximums. */ |
||
do j=1 for words(@fruits) /*process each of the names of fruits. */ |
|||
@=word(@fruits, j) /*obtain a fruit name from the list. */ |
|||
#=value('FRUIT.'@) /* " the quantity of a fruit. */ |
|||
if \p then do /*is this the first pass through ? */ |
|||
maxL=max(maxL, length(@)) /*the longest (widest) name of a fruit.*/ |
|||
maxQ=max(maxQ, length(#)) /*the widest width quantity of fruit. */ |
|||
iterate /*j*/ /*now, go get another name of a fruit. */ |
|||
end |
|||
if j==1 then say center('fruit', maxL) center("quantity", maxQ) |
|||
if j==1 then say copies('─' , maxL) copies("─" , maxQ) |
|||
if #\=0 then say right( @ , maxL) right( # , maxQ) |
|||
end /*j*/ |
|||
end |
end /*p*/ |
||
/*stick a fork in it, we're done.*/</ |
/*stick a fork in it, we're all done. */</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre> |
|||
<pre style="overflow:scroll"> |
|||
Yes! We have no bananas today. |
Yes! We have no bananas today. |
||
We gots 12 hairy fruit. |
We gots 12 hairy fruit. |
||
We gots 48 fuzzy fruit. |
We gots 48 fuzzy fruit. |
||
fruit quantity |
fruit quantity |
||
Line 963: | Line 1,863: | ||
watermelon 0.5 |
watermelon 0.5 |
||
</pre> |
</pre> |
||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring"> |
|||
apple = 0 |
|||
banana = 1 |
|||
cherry = 2 |
|||
see "apple : " + apple + nl |
|||
see "banana : " + banana + nl |
|||
see "cherry : " + cherry + nl |
|||
</syntaxhighlight> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
There are plenty of ways to represent '''enum''' in Ruby. Here it is just one example: |
There are plenty of ways to represent '''enum''' in Ruby. Here it is just one example: |
||
< |
<syntaxhighlight lang="ruby">module Fruits |
||
APPLE = 0 |
APPLE = 0 |
||
BANANA = 1 |
BANANA = 1 |
||
Line 976: | Line 1,886: | ||
FRUITS = [:apple, :banana, :cherry] |
FRUITS = [:apple, :banana, :cherry] |
||
val = :banana |
val = :banana |
||
FRUITS.include?(val) #=> true</ |
FRUITS.include?(val) #=> true</syntaxhighlight> |
||
To give a number in turn, there is the following method. |
To give a number in turn, there is the following method. |
||
< |
<syntaxhighlight lang="ruby">module Card |
||
# constants |
# constants |
||
SUITS = % |
SUITS = %i(Clubs Hearts Spades Diamonds) |
||
SUIT_VALUE = |
SUIT_VALUE = SUITS.each_with_index.to_h # version 2.1+ |
||
# SUIT_VALUE = Hash[ SUITS.each_with_index.to_a ] # before it |
|||
#=> {"Clubs"=>0, "Hearts"=>1, "Spades"=>2, "Diamonds"=>3} |
|||
#=> {:Clubs=>0, :Hearts=>1, :Spades=>2, :Diamonds=>3} |
|||
PIPS = %w(2 3 4 5 6 7 8 9 10 Jack Queen King Ace) |
|||
PIPS = %i(2 3 4 5 6 7 8 9 10 Jack Queen King Ace) |
|||
PIP_VALUE = Hash[ PIPS.each.with_index(2).to_a ] |
|||
PIP_VALUE = PIPS.each.with_index(2).to_h # version 2.1+ |
|||
#=> {"2"=>2, "3"=>3, "4"=>4, "5"=>5, "6"=>6, "7"=>7, "8"=>8, "9"=>9, "10"=>10, "Jack"=>11, "Queen"=>12, "King"=>13, "Ace"=>14} |
|||
# PIP_VALUE = Hash[ PIPS.each.with_index(2).to_a ] # before it |
|||
end</lang> |
|||
#=> {:"2"=>2, :"3"=>3, :"4"=>4, :"5"=>5, :"6"=>6, :"7"=>7, :"8"=>8, :"9"=>9, :"10"=>10, :Jack=>11, :Queen=>12, :King=>13, :Ace=>14} |
|||
end</syntaxhighlight> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang="rust">enum Fruits { |
||
Apple, |
Apple, |
||
Banana, |
Banana, |
||
Cherry |
Cherry |
||
} |
|||
}</lang> |
|||
enum FruitsWithNumbers { |
|||
Strawberry = 0, |
|||
Pear = 27, |
|||
} |
|||
fn main() { |
|||
// Access to numerical value by conversion |
|||
println!("{}", FruitsWithNumbers::Pear as u8); |
|||
}</syntaxhighlight> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
'''1. Using Algebraic Data Types:''' |
'''1. Using Algebraic Data Types:''' |
||
< |
<syntaxhighlight lang="actionscript">sealed abstract class Fruit |
||
case object Apple extends Fruit |
case object Apple extends Fruit |
||
case object Banana extends Fruit |
case object Banana extends Fruit |
||
case object Cherry extends Fruit |
case object Cherry extends Fruit |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''2. Using scala.Enumeration:''' |
'''2. Using scala.Enumeration:''' |
||
< |
<syntaxhighlight lang="actionscript">object Fruit extends Enumeration { |
||
val Apple, Banana, Cherry = Value |
val Apple, Banana, Cherry = Value |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
< |
<syntaxhighlight lang="scheme">(define apple 0) |
||
(define banana 1) |
(define banana 1) |
||
(define cherry 2) |
(define cherry 2) |
||
Line 1,016: | Line 1,939: | ||
(or (equal? 'apple atom) |
(or (equal? 'apple atom) |
||
(equal? 'banana atom) |
(equal? 'banana atom) |
||
(equal? 'cherry atom)))</ |
(equal? 'cherry atom)))</syntaxhighlight> |
||
(This section needs attention from someone familiar with Scheme idioms.) |
(This section needs attention from someone familiar with Scheme idioms.) |
||
===Using syntax extension=== |
|||
{{works with|Chez Scheme}} |
|||
'''The Implementation''' |
|||
<syntaxhighlight lang="scheme">; Syntax that implements a C-like enum; items without assignment take next value. |
|||
; Form: (enum <name> <item>...) |
|||
; Where <name> is a symbol that will be the name of the enum; <item> are one or |
|||
; more expressions that are either symbols or lists of symbol and integer value. |
|||
; The symbols are bound to the values. If a value is not given, then the next |
|||
; integer after the one bound to the previous symbol is used (starting at 0). |
|||
; The <name> itself is bound to an a-list of the item symbols and their values. |
|||
(define-syntax enum |
|||
(lambda (x) |
|||
(syntax-case x () |
|||
((_ name itm1 itm2 ...) |
|||
(identifier? (syntax name)) |
|||
(syntax |
|||
(begin |
|||
(define name '()) |
|||
(enum-help name 0 itm1 itm2 ...))))))) |
|||
; Helper for (enum) syntax, above. Do not call directly! |
|||
(define-syntax enum-help |
|||
(lambda (x) |
|||
(syntax-case x () |
|||
((_ name nxint) |
|||
(syntax (void))) |
|||
((_ name nxint (sym val) rest ...) |
|||
(and (identifier? (syntax sym)) |
|||
(integer? (syntax-object->datum (syntax val)))) |
|||
(syntax |
|||
(begin |
|||
(define sym val) |
|||
(set! name (cons (cons 'sym val) name)) |
|||
(enum-help name (1+ val) rest ...)))) |
|||
((_ name nxint sym rest ...) |
|||
(identifier? (syntax sym)) |
|||
(syntax |
|||
(begin |
|||
(define sym nxint) |
|||
(set! name (cons (cons 'sym nxint) name)) |
|||
(enum-help name (1+ nxint) rest ...)))))))</syntaxhighlight> |
|||
'''Example Use''' |
|||
<syntaxhighlight lang="scheme">(define-syntax test |
|||
(syntax-rules () |
|||
((_ e) |
|||
(printf "~a --> ~s~%" 'e e)))) |
|||
(printf "~%The 'foo' enum:~%") |
|||
(enum foo a (b 10) c (d 20) e (f 30) g) |
|||
(test a) |
|||
(test b) |
|||
(test c) |
|||
(test d) |
|||
(test e) |
|||
(test f) |
|||
(test g) |
|||
(test foo) |
|||
(test (assq 'd foo)) |
|||
(test (assq 'm foo)) |
|||
(printf "~%The 'bar' enum:~%") |
|||
(enum bar x y (z 99)) |
|||
(test x) |
|||
(test y) |
|||
(test z) |
|||
(test bar)</syntaxhighlight> |
|||
{{out}} |
|||
<pre>The 'foo' enum: |
|||
a --> 0 |
|||
b --> 10 |
|||
c --> 11 |
|||
d --> 20 |
|||
e --> 21 |
|||
f --> 30 |
|||
g --> 31 |
|||
foo --> ((g . 31) (f . 30) (e . 21) (d . 20) (c . 11) (b . 10) (a . 0)) |
|||
(assq 'd foo) --> (d . 20) |
|||
(assq 'm foo) --> #f |
|||
The 'bar' enum: |
|||
x --> 0 |
|||
y --> 1 |
|||
z --> 99 |
|||
bar --> ((z . 99) (y . 1) (x . 0))</pre> |
|||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang="seed7">const type: fruits is new enum |
||
apple, banana, cherry |
apple, banana, cherry |
||
end enum;</ |
end enum;</syntaxhighlight> |
||
=={{header|Shen}}== |
|||
<syntaxhighlight lang="shen">(tc +) |
|||
(datatype fruit |
|||
if (element? Fruit [apple banana cherry]) |
|||
_____________ |
|||
Fruit : fruit;)</syntaxhighlight> |
|||
=={{header|Sidef}}== |
|||
Implicit: |
|||
<syntaxhighlight lang="ruby">enum {Apple, Banana, Cherry}; # numbered 0 through 2</syntaxhighlight> |
|||
Explicit: |
|||
<syntaxhighlight lang="ruby">enum { |
|||
Apple=3, |
|||
Banana, # gets the value 4 |
|||
Cherry="a", |
|||
Orange, # gets the value "b" |
|||
};</syntaxhighlight> |
|||
=={{header|Slate}}== |
=={{header|Slate}}== |
||
As just unique objects: |
As just unique objects: |
||
< |
<syntaxhighlight lang="slate">define: #Fruit &parents: {Cloneable}. |
||
Fruit traits define: #Apple -> Fruit clone. |
Fruit traits define: #Apple -> Fruit clone. |
||
Fruit traits define: #Banana -> Fruit clone. |
Fruit traits define: #Banana -> Fruit clone. |
||
Fruit traits define: #Cherry -> Fruit clone.</ |
Fruit traits define: #Cherry -> Fruit clone.</syntaxhighlight> |
||
As labels for primitive values: |
As labels for primitive values: |
||
< |
<syntaxhighlight lang="slate">define: #Apple -> 1. |
||
define: #Banana -> 2. |
define: #Banana -> 2. |
||
define: #Cherry -> 3.</ |
define: #Cherry -> 3.</syntaxhighlight> |
||
As a namespace: |
As a namespace: |
||
< |
<syntaxhighlight lang="slate">ensureNamespace: #fruit &slots: {#Apple -> 1. #Banana -> 2. #Cherry -> 3}.</syntaxhighlight> |
||
Using a dictionary: |
Using a dictionary: |
||
< |
<syntaxhighlight lang="slate">define: #fruit &builder: [{#Apple -> 1. #Banana -> 2. #Cherry -> 3} as: Dictionary].</syntaxhighlight> |
||
=={{header|Standard ML}}== |
=={{header|Standard ML}}== |
||
< |
<syntaxhighlight lang="sml">datatype fruit = |
||
Apple |
Apple |
||
| Banana |
| Banana |
||
| Cherry</ |
| Cherry</syntaxhighlight> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">enum Fruit { |
||
case Apple |
case Apple |
||
case Banana |
case Banana |
||
Line 1,061: | Line 2,097: | ||
case Summer = 3 |
case Summer = 3 |
||
case Autumn = 4 |
case Autumn = 4 |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
It is normal in Tcl to use strings from a set directly rather than treating them as an enumeration, but enumerations can be simulated easily. The following elegant example comes straight from the [[http://wiki.tcl.tk/1308 Tcl wiki:]] |
It is normal in Tcl to use strings from a set directly rather than treating them as an enumeration, but enumerations can be simulated easily. The following elegant example comes straight from the [[http://wiki.tcl.tk/1308 Tcl wiki:]] |
||
< |
<syntaxhighlight lang="tcl">proc enumerate {name values} { |
||
interp alias {} $name: {} lsearch $values |
interp alias {} $name: {} lsearch $values |
||
interp alias {} $name@ {} lindex $values |
interp alias {} $name@ {} lindex $values |
||
}</ |
}</syntaxhighlight> |
||
it would be used like this: |
it would be used like this: |
||
< |
<syntaxhighlight lang="tcl">enumerate fruit {apple blueberry cherry date elderberry} |
||
fruit: date |
fruit: date |
||
# ==> prints "3" |
# ==> prints "3" |
||
fruit@ 2 |
fruit@ 2 |
||
# ==> prints "cherry"</ |
# ==> prints "cherry"</syntaxhighlight> |
||
=={{header|Toka}}== |
=={{header|Toka}}== |
||
Line 1,085: | Line 2,121: | ||
This library function takes a starting value and a list of names as shown in the example below. |
This library function takes a starting value and a list of names as shown in the example below. |
||
< |
<syntaxhighlight lang="toka">needs enum |
||
0 enum| apple banana carrot | |
0 enum| apple banana carrot | |
||
10 enum| foo bar baz |</ |
10 enum| foo bar baz |</syntaxhighlight> |
||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
Like Visual Basic .NET, actually: |
Like Visual Basic .NET, actually: |
||
<syntaxhighlight lang="vb"> |
|||
<lang vb> |
|||
'this enumerates from 0 |
'this enumerates from 0 |
||
Enum fruits |
Enum fruits |
||
Line 1,115: | Line 2,151: | ||
Debug.Print "cherry plus kiwi plus pineapple equals "; cherry + kiwi + pineapple |
Debug.Print "cherry plus kiwi plus pineapple equals "; cherry + kiwi + pineapple |
||
End Sub |
End Sub |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
test |
test |
||
Line 1,125: | Line 2,161: | ||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
< |
<syntaxhighlight lang="vbnet">' Is this valid?! |
||
Enum fruits |
Enum fruits |
||
apple |
apple |
||
Line 1,137: | Line 2,173: | ||
banana = 1 |
banana = 1 |
||
cherry = 2 |
cherry = 2 |
||
End Enum</ |
End Enum</syntaxhighlight> |
||
=={{header|Wren}}== |
|||
Wren doesn't support either enums or constants as such but a common way to indicate that a variable should not be mutated is to give it an upper case name and to group related variables together. |
|||
The only way to give such a variable a value without setting it explicitly is to add one to the previous such variable which (in effect) is what a C-style enum does. If you declare a variable in Wren without giving it a value, then it is set to the special value ''null'' which is no help here. |
|||
<syntaxhighlight lang="wren">var APPLE = 1 |
|||
var ORANGE = 2 |
|||
var PEAR = 3 |
|||
var CHERRY = 4 |
|||
var BANANA = CHERRY + 1 |
|||
var GRAPE = BANANA + 1 |
|||
System.print([APPLE, ORANGE, PEAR, CHERRY, BANANA, GRAPE])</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[1, 2, 3, 4, 5, 6] |
|||
</pre> |
|||
<br> |
|||
It is also possible to create an enum-like class using read-only static properties to get the values. The following code creates such a class dynamically at runtime. Note that the convention in Wren is for properties to begin with a lower-case letter. |
|||
<br> |
|||
{{libheader|Wren-dynamic}} |
|||
<syntaxhighlight lang="wren">import "./dynamic" for Enum |
|||
var Fruit = Enum.create("Fruit", ["apple", "orange", "pear", "cherry", "banana", "grape"], 1) |
|||
System.print(Fruit.orange) |
|||
System.print(Fruit.members[Fruit.cherry - 1])</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
2 |
|||
cherry |
|||
</pre> |
|||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">def \Fruit\ Apple, Banana, Cherry; \Apple=0, Banana=1, Cherry=2 |
||
def Apple=1, Banana=2, Cherry=4; |
def Apple=1, Banana=2, Cherry=4; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Z80 Assembly}}== |
|||
{{trans|6502 Assembly}} |
|||
===With Explicit Values=== |
|||
You can use labels to "name" any numeric value, whether it represents a constant or a memory location is up to the programmer. Code labels are automatically assigned a value based on what memory location they are assembled to. |
|||
Keep in mind that these names do not exist at runtime and are just for the programmer's convenience. None of this "code" below actually takes up any space in the assembled program. |
|||
<syntaxhighlight lang="z80">Sunday equ 0 |
|||
Monday equ 1 |
|||
Tuesday equ 2 |
|||
Wednesday equ 3 |
|||
Thursday equ 4 |
|||
Friday equ 5 |
|||
Saturday equ 6</syntaxhighlight> |
|||
===Without Explicit Values=== |
|||
A lookup table is the most common method of enumeration of actual data in assembly. Each element of the table can be accessed by an index, and the starting index is zero. (The index may need to be adjusted for data sizes larger than 1 byte, i.e. doubled for 16-bit data and quadrupled for 32-bit data.) Unlike the above example, these values do indeed take up memory. Using this method when the above enumeration would suffice is incredibly wasteful. |
|||
<syntaxhighlight lang="z80">align 8 ;aligns "Days_Of_The_Week" to the next 256-byte boundary. The low byte of "Sunday" will be at memory location &XX00. |
|||
;this simplifies the lookup process significantly. |
|||
Days_Of_The_Week: |
|||
word Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday |
|||
Sunday: |
|||
byte "Sunday",0 |
|||
Monday: |
|||
byte "Monday",0 |
|||
Tuesday: |
|||
byte "Tuesday",0 |
|||
Wednesday: |
|||
byte "Wednesday",0 |
|||
Thursday: |
|||
byte "Thursday",0 |
|||
Friday: |
|||
byte "Friday",0 |
|||
Saturday: |
|||
byte "Saturday",0 |
|||
;This example will load Friday. |
|||
ld hl,Days_Of_The_Week ;get base address of table. (Thanks to the align 8, we know that L = 0.) |
|||
ld a,5 ;0 = Sunday, 1 = Monday, ... 5 = Friday, 6 = Saturday |
|||
add a ;Multiply A by 2 (this is faster than SLA A. RLCA would have also worked here) |
|||
ld L,a ;since the table was page-aligned it is sufficient to load A directly into L to properly index the table. |
|||
ld e,(hl) ;get the low byte into E |
|||
inc hl ;increment HL to high byte |
|||
ld d,(hl) ;get the high byte into D |
|||
;now DE contains the pointer to "Friday" |
|||
ex de,hl ;my PrintString routine takes the pointer in HL as the argument so we need to swap DE with HL. |
|||
call PrintString ;prints a null-terminated string to the screen. |
|||
ret ;return to basic |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Friday |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
Enums as thing or type is not supported but they can be simulated by running code at parse time (ie modify the AST before the compiler compiles it). |
|||
<syntaxhighlight lang="zkl">const RGB_COLOR{ // put color names in a name space |
|||
const RED =0xf00; |
|||
const BLUE=0x0f0, GREEN = 0x00f; |
|||
const CYAN=BLUE + GREEN; // → 0x0ff |
|||
} |
|||
println(RGB_COLOR.BLUE);</syntaxhighlight> |
|||
{{out}} |
|||
<pre>240</pre> |
|||
<syntaxhighlight lang="zkl">const X0=N; // --> 0 |
|||
const A=N,B=N,C=N; // --> 1,2,3 |
|||
const{ _n=-1; } // reset Enum, this should be a const space function |
|||
const X=N; // -->0</syntaxhighlight> |
|||
Since const space runs at a different time [vs compile space], you need to really careful if you mix the two [spaces]: |
|||
<syntaxhighlight lang="zkl">#continuing ... |
|||
z:=N; // -->2 NOT 1 as it is set AFTER Y (compile time vs parse time) |
|||
const Y=N; // -->1! because it is set before z</syntaxhighlight> |
|||
=={{header|zonnon}}== |
|||
<syntaxhighlight lang="zonnon"> |
|||
module Enumerations; |
|||
type |
|||
Fruits = (apple,banana,cherry); |
|||
var |
|||
deserts,i: Fruits; |
|||
begin |
|||
deserts := Fruits.banana; |
|||
writeln("ord(deserts): ",integer(deserts):2); |
|||
for i := Fruits.apple to Fruits.cherry do |
|||
writeln(integer(i):2) |
|||
end |
|||
end Enumerations. |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
ord(deserts): 1 |
|||
0 |
|||
1 |
|||
2 |
|||
</pre> |
|||
{{omit from|PARI/GP}} |
{{omit from|PARI/GP}} |
||
Line 1,148: | Line 2,321: | ||
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Does not have user-defined data structures. --> |
{{omit from|TI-83 BASIC}} {{omit from|TI-89 BASIC}} <!-- Does not have user-defined data structures. --> |
||
{{omit from|ZX Spectrum Basic}} <!-- It is not worthwhile enumerating, because variable names are single letters --> |
{{omit from|ZX Spectrum Basic}} <!-- It is not worthwhile enumerating, because variable names are single letters --> |
||
{{omit from|Axe}} |
Latest revision as of 10:14, 30 November 2023
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Create an enumeration of constants with and without explicit values.
11l
T.enum TokenCategory
NAME
KEYWORD
CONSTANT
TEST_CATEGORY = 10
6502 Assembly
With Explicit Values
You can use labels to "name" any numeric value, whether it represents a constant or a memory location is up to the programmer. Code labels are automatically assigned a value based on what memory location they are assembled to.
Keep in mind that these names do not exist at runtime and are just for the programmer's convenience. None of this "code" below actually takes up any space in the assembled program.
Sunday equ 0
Monday equ 1
Tuesday equ 2
Wednesday equ 3
Thursday equ 4
Friday equ 5
Saturday equ 6
Some assemblers have an actual ENUM
directive, where only the 0th element needs a defined value and the rest follow sequentially. This is often used for allocating RAM locations rather than a C-style enumeration, however. .DSB
is a directive that stands for "data storage byte" and is listed after the label so that the assembler knows how big the variable is. In the example below the variable OBJECT_XPOS
begins at $0400 and OBJECT_XPOS
begins at $0410:
enum $0400
OBJECT_XPOS .dsb 16 ;define 16 bytes for object X position
OBJECT_YPOS .dsb 16 ;define 16 bytes for object Y position
ende
Without Explicit Values
A lookup table is the most common method of enumeration of actual data in assembly. Each element of the table can be accessed by an index, and the starting index is zero. (The index may need to be adjusted for data sizes larger than 1 byte, i.e. doubled for 16-bit data and quadrupled for 32-bit data.) Unlike the above example, these values do indeed take up memory. Using this method when the above enumeration would suffice is incredibly wasteful.
Days_Of_The_Week:
word Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
Sunday:
byte "Sunday",0
Monday:
byte "Monday",0
Tuesday:
byte "Tuesday",0
Wednesday:
byte "Wednesday",0
Thursday:
byte "Thursday",0
Friday:
byte "Friday",0
Saturday:
byte "Saturday",0
LDA #$03 ;we want to load Wednesday
ASL A ;these are 16-bit pointers to strings, so double A
TAX ;transfer A to X so that we can use this index as a lookup
LDA Days_Of_The_Week,x ;get low byte
STA $00 ;store in zero page memory
LDA Days_Of_The_Week+1,x ;get high byte
STA $01 ;store in zero page memory directly after low byte
LDY #0 ;clear Y
LDA ($00),Y ;Load the "W" of Wednesday into accumulator
68000 Assembly
With Explicit Values
You can use labels to "name" any numeric value, whether it represents a constant or a memory location is up to the programmer. Code labels are automatically assigned a value based on what memory location they are assembled to. The syntax for labels depends on your assembler; the example below uses VASM syntax and Motorola mnemonics.
Keep in mind that these names do not exist at runtime and are just for the programmer's convenience. None of this "code" below actually takes up any space in the assembled program.
Sunday equ 0
Monday equ 1
Tuesday equ 2
Wednesday equ 3
Thursday equ 4
Friday equ 5
Saturday equ 6
Without Explicit Values
A lookup table is the most common method of enumeration of actual data in assembly. Each element of the table can be accessed by an index, and the starting index is zero. (The index may need to be adjusted for data sizes larger than 1 byte, i.e. doubled for 16-bit data and quadrupled for 32-bit data.) Unlike the above example, these values do indeed take up memory. Using this method when the above enumeration would suffice is incredibly wasteful.
Like in a C-style enumeration, Sunday would be 0, Monday 1, Tuesday 2, and so on. (Actually, Monday would be 4 and Tuesday would be 8 and so on, since these are 32-bit pointers.) It's a common practice to have the index live in RAM as a one-byte index, load it in a register, and then scale its register copy during the lookup process only. That way if multiple tables with different data sizes have a common index, the program doesn't need to remember which data type the index was last used to access.
Days_Of_The_Week:
DC.L Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
Sunday:
DC.B "Sunday",0
EVEN ;conditionally aligns to a 2-byte boundary if the data isn't aligned already
Monday:
DC.B "Monday",0
EVEN
Tuesday:
DC.B "Tuesday",0
EVEN
Wednesday:
DC.B "Wednesday",0
EVEN
Thursday:
DC.B "Thursday",0
EVEN
Friday:
DC.B "Friday",0
EVEN
Saturday:
DC.B "Saturday",0
EVEN
;In this example, load Thursday.
LEA Days_Of_The_Week,A0 ;load base address of table into A0
MOVE.W #4,D0 ;Thursday's index
LSL.W #2,D0 ;multiply by 4 since each pointer is 32-bit
LEA (A0,D0),A1 ;load table offset by D0 into A1
MOVE.L (A1),A1 ;dereference the pointer, now the address of "Thursday" is in A1.
MOVE.B (A1)+,D1 ;Load the "T" of Thursday into D1, auto-increment to next letter for the next load.
8086 Assembly
With Explicit Values
Most assemblers allow the use of an equ
directive or something similar, where you can assign a label to a number for later use. These do not take up space in your program.
Sunday equ 0
Monday equ 1
Tuesday equ 2
Wednesday equ 3
Thursday equ 4
Friday equ 5
Saturday equ 6
Sunday equ 7
Without Explicit Values
A lookup table is often used to translate data according to a common index. The XLAT
instruction can help us with this task, however that instruction only works with 8-bit data, which is not always what we're after. In this example, we're using numbers 0 through 7 to look up a table of pointers to strings. When declaring a table like this, these DO take up space in your program.
mov ax,seg DaysOfTheWeek
mov ds,ax
mov si,offset DaysOfTheWeek
mov bx,2 ;desired enumeration of 2 = Tuesday
add bx,bx ;double bx since this is a table of words
mov ax,[bx+si] ;load the address of the string "Tuesday" into ax
mov si,ax ;we can't load indirectly from AX, so move it into SI. We don't need the old value of SI anymore
mov al,[si] ;load the byte at [SI] (in this case, the "T" in Tuesday.)
ret
DaysOfTheWeek word Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
;each is a pointer to a string containing the text you would expect.
ACL2
ACL2 doesn't have built-in enumerated types, but these macros add some basic support:
(defun symbol-to-constant (sym)
(intern (concatenate 'string "*" (symbol-name sym) "*")
"ACL2"))
(defmacro enum-with-vals (symbol value &rest args)
(if (endp args)
`(defconst ,(symbol-to-constant symbol) ,value)
`(progn (defconst ,(symbol-to-constant symbol) ,value)
(enum-with-vals ,@args))))
(defun interleave-with-nats-r (xs i)
(if (endp xs)
nil
(cons (first xs)
(cons i (interleave-with-nats-r (rest xs)
(1+ i))))))
(defun interleave-with-nats (xs)
(interleave-with-nats-r xs 0))
(defmacro enum (&rest symbols)
`(enum-with-vals ,@(interleave-with-nats symbols)))
Ada
Ada enumeration types have three distinct attributes, the enumeration literal, the enumeration position, and the representation value. The position value (starting with 0) is implied from the order of specification of the enumeration literals in the type declaration; it provides the ordering for the enumeration values. In the example below, apple (position 0) is less than banana (position 1) which is less than cherry (position 3) due to their positions, not due to their enumeration literal. An enumeration representation, when given, must not violate the order.
type Fruit is (apple, banana, cherry); -- No specification of the representation value;
for Fruit use (apple => 1, banana => 2, cherry => 4); -- specification of the representation values
Ada enumeration types are non-numeric discrete types. They can be used to index arrays, but there are no arithmetic operators for enumeration types; instead, there are predecessor and successor operations. Characters are implemented as an enumeration type in Ada.
ALGOL 68
Note: In this first example ALGOL 68's MODE does not create FRUITS as a distinct enumerated type. In particular FRUITS remain compatible with INT and so FRUITS inherit/share all INT's operators and procedures.
BEGIN # example 1 #
MODE FRUIT = INT;
FRUIT apple = 1, banana = 2, cherry = 4;
FRUIT x := cherry;
CASE x IN
print(("It is an apple #",x, new line)),
print(("It is a banana #",x, new line)),
SKIP, # 3 not defined #
print(("It is a cherry #",x, new line))
OUT
SKIP # other values #
ESAC
END;
- Output:
It is a cherry # +4
In this second example ALGOL 68's tagged unions are used to generate the (private) values of the members of the enumerated type. However this new type comes with no operators, not even the "=" equality operator. Hence at least REPR (or ABS for INT type) must be defined if anything other then a case conditional clause is required.
BEGIN # example 2 #
MODE ENUM = [0]CHAR; # something with minimal size #
MODE APPLE = STRUCT(ENUM apple), BANANA = STRUCT(ENUM banana), CHERRY = STRUCT(ENUM cherry);
MODE FRUIT = UNION(APPLE, BANANA, CHERRY);
OP REPR = (FRUIT f)STRING:
CASE f IN
(APPLE):"Apple",
(BANANA):"Banana",
(CHERRY):"Cherry"
OUT
"?" # uninitalised #
ESAC;
FRUIT x := LOC CHERRY;
CASE x IN
(APPLE):print(("It is an ",REPR x, new line)),
(BANANA):print(("It is a ",REPR x, new line)),
(CHERRY):print(("It is a ",REPR x, new line))
OUT
SKIP # uninitialised FRUIT #
ESAC
END
- Output:
It is a Cherry
Warning: This second example is probably not how the conformity case clause construct was intended to be used.
See also: Standard Deviation for another example.
AmigaE
ENUM APPLE, BANANA, CHERRY
PROC main()
DEF x
ForAll({x}, [APPLE, BANANA, CHERRY],
`WriteF('\d\n', x))
ENDPROC
writes 0, 1, 2 to the console.
Arturo
enum: [apple banana cherry]
print "as a block of words:"
inspect.muted enum
enum: ['apple 'banana 'cherry]
print "\nas a block of literals:"
print enum
enum: #[
apple: 1
banana: 2
cherry: 3
]
print "\nas a dictionary:"
print enum
- Output:
as a block of words: [ :block apple :word banana :word cherry :word ] as a block of literals: apple banana cherry as a dictionary: [apple:1 banana:2 cherry:3]
ATS
The wording of the task seems centered on C, where an enum is a notation for type int, but it is true that the following type will be translated by the ATS compiler to C integers:
datatype my_enum =
| value_a
| value_b
| value_c
Within ATS itself, my_enum is a special case of recursive type definition. Similar facilities are available in ML dialects and other languages.
To "enumerate" with explicit integer values, I would simply define some constants, probably with #define (so I could use them in static expressions, etc.):
#define value_a 1
#define value_b 2
#define value_c 3
You could still restrict things so no other values were possible:
typedef my_enum = [i : int | value_a <= i; i <= value_c] int i
The value of a my_enum would be enforced at compile time.
AutoHotkey
AutoHotkey doesn't really enforce types.
However you can simulate types like enumeration with associative arrays:
fruit_%apple% = 0
fruit_%banana% = 1
fruit_%cherry% = 2
AWK
In awk we can use an array, for mapping both ways, or initialize variables:
fruit["apple"]=1; fruit["banana"]=2; fruit["cherry"]=3
fruit[1]="apple"; fruit[2]="banana"; fruit[3]="cherry"
i=0; apple=++i; banana=++i; cherry=++i;
BASIC
REM Impossible. Can only be faked with arrays of strings.
OPTION BASE 1
DIM SHARED fruitsName$(1 to 3)
DIM SHARED fruitsVal%( 1 to 3)
fruitsName$[1] = "apple"
fruitsName$[2] = "banana"
fruitsName$[3] = "cherry"
fruitsVal%[1] = 1
fruitsVal%[2] = 2
fruitsVal%[3] = 3
REM OR GLOBAL CONSTANTS
DIM SHARED apple%, banana%, cherry%
apple% = 1
banana% = 2
cherry% = 3
BaCon
BaCon includes an ENUM statement, with or without fixed values. If no value is given, enumerations start at zero and increase by integer 1.
' Enumerations
' Start at zero
ENUM
cat, dog, parrot
END ENUM
PRINT "Dogs are #", dog
' Set value
ENUM
Sunday=1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
END ENUM
PRINT Sunday, " ", Wednesday, " ", Saturday
' Change values, ENUM names must be unique
ENUM
sunday=7, monday=1, tuesday, wednesday, thursday, friday, saturday
END ENUM
PRINT sunday, " ", wednesday, " ", saturday
- Output:
prompt$ ./enums Dogs are #1 1 4 7 7 3 6
Bracmat
Wikipedia says: 'An enumeration is a collection of items that is a complete, ordered listing of all of the items in that collection.' So the task is taken to be: 'Create a collection of constants that is a complete, ordered listing of all of the constants in that collection, with and without explicit values.' In Bracmat, each expression is a constant and can be used in situations where one would use an enum in other languages. All expressions have an ordering in sums and products. In the case of non-numeric strings the ordering is alphabetic. It is not possible in Bracmat to have a constant without an explicit value, because the constant is nothing but the value, so only half of the task can be solved.
fruits=apple+banana+cherry;
C
enum fruits { apple, banana, cherry };
enum fruits { apple = 0, banana = 1, cherry = 2 };
However, if defined like the above, in C you must use the type as enum fruits
, not just fruits
. A common practice in C (same with struct
s) is to instead typedef the enum so you can refer to the type as a bare name:
typedef enum { apple, banana, cherry } fruits;
typedef enum { apple = 0, banana = 1, cherry = 2 } fruits;
C#
enum fruits { apple, banana, cherry }
enum fruits { apple = 0, banana = 1, cherry = 2 }
enum fruits : int { apple = 0, banana = 1, cherry = 2 }
[FlagsAttribute]
enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 }
Placing FlagsAttribute before an enum allows you to perform bitwise operations on the value. Note: All enums have a value of 0 defined, even if not specified in the set values.
C++
enum fruits { apple, banana, cherry };
enum fruits { apple = 0, banana = 1, cherry = 2 };
Note that, unlike in C, you can refer to the type here as fruits
.
C++11 introduced "strongly typed enumerations", enumerations that cannot be implicitly converted to/from integers:
enum class fruits { apple, banana, cherry };
enum class fruits { apple = 0, banana = 1, cherry = 2 };
These enumeration constants must be referred to as fruits::apple
, not just apple
.
You can explicitly specify an underlying type for the enum; the default is int
:
enum class fruits : unsigned int { apple, banana, cherry };
You can also explicitly specify an underlying type for old-style enums:
enum fruits : unsigned int { apple, banana, cherry };
Clojure
In Clojure you will typically use keywords when you would use enums in other languages. Keywords are symbols that start with a colon and evaluate to themselves. For example:
; a set of keywords
(def fruits #{:apple :banana :cherry})
; a predicate to test "fruit" membership
(defn fruit? [x] (contains? fruits x))
; if you need a value associated with each fruit
(def fruit-value (zipmap fruits (iterate inc 1)))
(println (fruit? :apple))
(println (fruit-value :banana))
Common Lisp
Values:
;; symbol to number
(defconstant +apple+ 0)
(defconstant +banana+ 1)
(defconstant +cherry+ 2)
;; number to symbol
(defun index-fruit (i)
(aref #(+apple+ +banana+ +cherry+) i))
Of course, the two definitions above can be produced by a single macro, if desired.
Defining a type for documentation or checking purposes:
(deftype fruit ()
'(member +apple+ +banana+ +cherry+))
Computer/zero Assembly
Constants can be defined by simply storing their binary representation into memory. You've only got 32 bytes of RAM so don't waste them. This is the only way to use numeric values, as all instructions on the CPU take memory addresses as operands, not constants.
LDA 4 ;load from memory address 4
STP
NOP
NOP
byte 1
The NOP
and STP
instructions ignore their operands, which means you can store arbitrary data inside those instructions that you can load from. This can save a little bit of memory.
D
void main() {
// Named enumeration (commonly used enum in D).
// The underlying type is a 32 bit int.
enum Fruits1 { apple, banana, cherry }
// You can assign an enum to the general type, but not the opposite:
int f1 = Fruits1.banana; // No error.
// Fruits1 f2 = 1; // Error: cannot implicitly convert.
// Anonymous enumeration, as in C, of type 32 bit int.
enum { APPLE, BANANA, CHERRY }
static assert(CHERRY == 2);
// Named enumeration with specified values (int).
enum Fruits2 { apple = 0, banana = 10, cherry = 20 }
// Named enumeration, typed and with specified values.
enum Fruits3 : ubyte { apple = 0, banana = 100, cherry = 200 }
// Named enumeration, typed and with partially specified values.
enum Test : ubyte { A = 2, B, C = 3 }
static assert(Test.B == 3); // Uses the next ubyte, duplicated value.
// This raises a compile-time error for overflow.
// enum Fruits5 : ubyte { apple = 254, banana = 255, cherry }
enum Component {
none,
red = 2 ^^ 0,
green = 2 ^^ 1,
blue = 2 ^^ 2
}
// Phobos BitFlags support all the most common operations on flags.
// Some of the operations are shown below.
import std.typecons: BitFlags;
alias ComponentFlags = BitFlags!Component;
immutable ComponentFlags flagsEmpty;
// Value can be set with the | operator.
immutable flagsRed = flagsEmpty | Component.red;
immutable flagsGreen = ComponentFlags(Component.green);
immutable flagsRedGreen = ComponentFlags(Component.red, Component.green);
immutable flagsBlueGreen = ComponentFlags(Component.blue, Component.green);
// Use the & operator between BitFlags for intersection.
assert (flagsGreen == (flagsRedGreen & flagsBlueGreen));
}
Delphi
In addition to standard Pascal, one may explicitly specify an index:
type
fruit = (apple, banana, cherry);
ape = (gorilla = 0, chimpanzee = 1, orangutan = 5);
Note, explicit indices have to be in ascending order. You can also just specify explicit indices for some items.
Diego
Enumerations can have extra information appended such as static
(static variable name); colour
(human friendly colour name); color
(robot friendly colour name); and desc
(description used for robots to communicate with humans).
With explicit values:
add_enum(⟪{int}⟫,⟦{str}⟧,urgency)
()_enum(⟪4⟫,⟦emergent⟧)_static(URGENCY_EMERGENT)_colour(red)_color({hex},#ca0031)_desc(The most urgent (critical) state, severe risk.);
()_enum(⟪3⟫,⟦exigent⟧)_static(URGENT_EXIGENT)_colour(orange)_color({hex},#ff6400)_desc(The high urgent state, high risk.);
()_enum(⟪2⟫,⟦urgent⟧)_static(URGENT_URGENT)_colour(yellow)_color({hex},#fce001)_desc(The elevated urgent state, elevated risk.);
()_enum(⟪1⟫,⟦infergent⟧)_static(URGENT_INFERGENT)_colour(blue)_color({hex},#3566cd)_desc(The low urgent state, low / guarded risk.);
()_enum(⟪0⟫,⟦nonurgent⟧)_static(URGENT_NON)_colour(green)_color({hex},#009a66)_desc(The non-urgent state, negligible risk.);
;
Without explicit values (and dynamic typing):
add_enum(fruits,⟦apple,banana,cherry⟧);
Flag enumerations (multi-selectable enumerations) can be created using enum
, however, there is an primitive flag
object available. This is similar to [Flags]
and <Flags> _
flag attributes in C# and VB.Net respectively.
add_flag(ape,⟦gorilla,chimpanzee,orangutan⟧);
log_console()_(ape);
Output:
⟪1⟫,⟦gorilla⟧,⟪2⟫,⟦chimpanzee⟧,⟪4⟫,⟦orangutan⟧
DWScript
type TFruit = (Apple, Banana, Cherry);
type TApe = (Gorilla = 0, Chimpanzee = 1, Orangutan = 5);
E
Simple group of object definitions (value methods could be left out if appropriate):
def apple { to value() { return 0 } }
def banana { to value() { return 1 } }
def cherry { to value() { return 2 } }
With a guard for type checks:
interface Fruit guards FruitStamp {}
def apple implements FruitStamp {}
def banana implements FruitStamp {}
def cherry implements FruitStamp {}
def eat(fruit :Fruit) { ... }
With and without values, using a hypothetical enumeration library:
def [Fruit, [=> apple, => banana, => cherry]] := makeEnumeration()
def [Fruit, [=> apple, => banana, => cherry]] :=
makeEnumeration(0, ["apple", "banana", "cherry"])
EGL
// Without explicit values
enumeration FruitsKind
APPLE,
BANANA,
CHERRY
end
program EnumerationTest
function main()
whatFruitAmI(FruitsKind.CHERRY);
end
function whatFruitAmI(fruit FruitsKind)
case (fruit)
when(FruitsKind.APPLE)
syslib.writestdout("You're an apple.");
when(FruitsKind.BANANA)
syslib.writestdout("You're a banana.");
when(FruitsKind.CHERRY)
syslib.writestdout("You're a cherry.");
otherwise
syslib.writestdout("I'm not sure what you are.");
end
end
end
-and-
// With explicit values
library FruitsKind type BasicLibrary {}
const APPLE int = 0;
const BANANA int = 1;
const CHERRY int = 2;
end
program EnumerationTest
function main()
whatFruitAmI(FruitsKind.CHERRY);
end
function whatFruitAmI(fruit int in)
case (fruit)
when(FruitsKind.APPLE)
syslib.writestdout("You're an apple.");
when(FruitsKind.BANANA)
syslib.writestdout("You're a banana.");
when(FruitsKind.CHERRY)
syslib.writestdout("You're a cherry.");
otherwise
syslib.writestdout("I'm not sure what you are.");
end
end
end
Elixir
It is possible to use a atom if the value is unrelated.
fruits = [:apple, :banana, :cherry]
fruits = ~w(apple banana cherry)a # Above-mentioned different notation
val = :banana
Enum.member?(fruits, val) #=> true
val in fruits #=> true
If they have to have a specific value
fruits = [{:apple, 1}, {:banana, 2}, {:cherry, 3}] # Keyword list
fruits = [apple: 1, banana: 2, cherry: 3] # Above-mentioned different notation
fruits[:apple] #=> 1
Keyword.has_key?(fruits, :banana) #=> true
fruits = %{:apple=>1, :banana=>2, :cherry=>3} # Map
fruits = %{apple: 1, banana: 2, cherry: 3} # Above-mentioned different notation
fruits[:apple] #=> 1
fruits.apple #=> 1 (Only When the key is Atom)
Map.has_key?(fruits, :banana) #=> true
To give a number in turn, there is the following method.
# Keyword list
fruits = ~w(apple banana cherry)a |> Enum.with_index
#=> [apple: 0, banana: 1, cherry: 2]
# Map
fruits = ~w(apple banana cherry)a |> Enum.with_index |> Map.new
#=> %{apple: 0, banana: 1, cherry: 2}
EMal
in Org:RosettaCode
type Fruits
enum
int APPLE, BANANA, CHERRY
end
type ExplicitFruits
enum
int APPLE = 10
int BANANA = 20
int CHERRY = 1
end
type Main
for each generic enumeration in generic[Fruits, ExplicitFruits]
writeLine("[" + Generic.name(enumeration) + "]")
writeLine("getting an object with value = 1:")
writeLine(:enumeration.byValue(1))
writeLine("iterating over the items:")
for each var fruit in :enumeration
writeLine(fruit)
end
writeLine()
end
- Output:
[Org:RosettaCode:Fruits] getting an object with value = 1: BANANA(1) iterating over the items: APPLE(0) BANANA(1) CHERRY(2) [Org:RosettaCode:ExplicitFruits] getting an object with value = 1: CHERRY(1) iterating over the items: APPLE(10) BANANA(20) CHERRY(1)
Erlang
For the unspecific value enum use case, Erlang has atoms. You can use apple, banana, orange directly in the code. If they have to have a specific value they could be grouped like this: {apple, 1}, {banana, 3}, {orange, 8}
F#
Enumerations in F# always have explicit values:
type Fruit =
| Apple = 0
| Banana = 1
| Cherry = 2
let basket = [ Fruit.Apple ; Fruit.Banana ; Fruit.Cherry ]
Seq.iter (printfn "%A") basket
If the initialization values are omitted, the resulting type is a discriminated union (algebraic data type) instead. Simple discriminated unions can be used similarly to enumerations, but they are never convertible from and to integers, and their internal representation is quite different.
type Fruit =
| Apple
| Banana
| Cherry
let basket = [ Apple ; Banana ; Cherry ]
Seq.iter (printfn "%A") basket
Factor
Enumerations are essentially association lists with values (keys) assigned sequentially from constants (values) provided by an initial sequence.
IN: scratchpad { "sun" "mon" "tue" "wed" "thur" "fri" "sat" } <enum>
--- Data stack:
T{ enum f ~array~ }
IN: scratchpad [ 1 swap at ] [ keys ] bi
--- Data stack:
"mon"
{ 0 1 2 3 4 5 6 }
Factor also provides C-like enumerations in its C library interface. These enumerations may have explicit values.
IN: scratchpad USE: alien.syntax
IN: scratchpad ENUM: day sun mon { tue 42 } wed thur fri sat ;
IN: scratchpad 1 <day>
--- Data stack:
mon
IN: scratchpad 42 <day>
--- Data stack:
mon
tue
Fantom
Enumerations with named constants:
// create an enumeration with named constants
enum class Fruits { apple, banana, orange }
A private constructor can be added to initialise internal fields, which must be constant.
// create an enumeration with explicit values
enum class Fruits_
{
apple (1), banana (2), orange (3)
const Int value
private new make (Int value) { this.value = value }
}
Forth
Forth has no types, and therefore no enumeration type. To define sequential constants, a programmer might write code like this:
0 CONSTANT apple
1 CONSTANT banana
2 CONSTANT cherry
...
However, a common idiom in forth is to define a defining word, such as:
: ENUM ( n -<name>- n+1 ) DUP CONSTANT 1+ ;
This word defines a new constant of the value specified and returns the next value in sequence. It would be used like this:
0 ENUM APPLE ENUM BANANA ENUM CHERRY DROP
Or you can use CONSTANT to capture the "end" value instead of dropping it:
0 ENUM FIRST ENUM SECOND ... CONSTANT LAST
A variation of this idea is the "stepped enumeration" that increases the value by more than 1, such as:
: SIZED-ENUM ( n s -<name>- n+s ) OVER CONSTANT + ;
: CELL-ENUM ( n -<name>- n+cell ) CELL SIZED-ENUM ;
A programmer could combine these enum definers in any way desired:
0 ENUM FIRST \ value = 0
CELL-ENUM SECOND \ value = 1
ENUM THIRD \ value = 5
3 SIZED-ENUM FOURTH \ value = 6
ENUM FIFTH \ value = 9
CONSTANT SIXTH \ value = 10
Note that a similar technique is often used to implement structures in Forth.
For a simple zero-based sequence of constants, one could use a loop in the defining word:
: CONSTANTS ( n -- ) 0 DO I CONSTANT LOOP ;
\ resistor digit colors
10 CONSTANTS black brown red orange yellow green blue violet gray white
Fortran
enum, bind(c)
enumerator :: one=1, two, three, four, five
enumerator :: six, seven, nine=9
end enum
The syntax
enum, bind(c) :: nametype
enumerator :: one=1, two, three
end enum nametype
does not work with gfortran; it is used in some Cray docs about Fortran, but the syntax shown at IBM is the one gfortran can understand. (Cray's docs refer to Fortran 2003 draft, IBM docs refers to Fortran 2003 standard, but read the brief Fortran 2003 Standard section to understand why differences may exist...)
Free Pascal
See Delphi. Note, depending on the {$scopedEnum} compiler switch (as of definition time), enumeration type members are identified via the type name prepended.
Additionally, enumeration types can be passed to write/writeLn producing the Pascal (source code) identifier.
FreeBASIC
' FB 1.05.0 Win64
Enum Animals
Cat
Dog
Zebra
End Enum
Enum Dogs
Bulldog = 1
Terrier = 2
WolfHound = 4
End Enum
Print Cat, Dog, Zebra
Print Bulldog, Terrier, WolfHound
Sleep
- Output:
0 1 2 1 2 4
FutureBasic
window 1, @"Enumerations", (0,0,480,270)
begin enum 1
_apple
_banana
_cherry
end enum
begin enum
_appleExplicit = 10
_bananaExplicit = 15
_cherryExplicit = 30
end enum
print "_apple = "; _apple
print "_banana = "; _banana
print "_cherry = "; _cherry
print
print "_appleExplicit = "; _appleExplicit
print "_bananaExplicit = "; _bananaExplicit
print "_cherryExplicit = "; _cherryExplicit
HandleEvents
Output
_apple = 1 _banana = 2 _cherry = 3 _appleExplicit = 10 _bananaExplicit = 15 _cherryExplicit = 30
Go
Go's enumeration-like feature is called iota. It generates sequential integer constants.
const (
apple = iota
banana
cherry
)
The above is equivalent to,
const (
apple = 0
banana = 1
cherry = 2
)
Constants in Go are not typed they way variables are, they are typed when used just like literal constants. Here is an example of a type safe enumeration:
type fruit int
const (
apple fruit = iota
banana
cherry
)
And using explicit values (note each constant must be individual typed here unlike with iota):
type fruit int
const (
apple fruit = 0
banana fruit = 1
cherry fruit = 2
)
Groovy
Enumerations:
enum Fruit { apple, banana, cherry }
enum ValuedFruit {
apple(1), banana(2), cherry(3);
def value
ValuedFruit(val) {value = val}
String toString() { super.toString() + "(${value})" }
}
println Fruit.values()
println ValuedFruit.values()
- Output:
[apple, banana, cherry] [apple(1), banana(2), cherry(3)]
Haskell
data Fruit = Apple | Banana | Cherry deriving Enum
Huginn
enum FRUIT {
APPLE,
BANANA,
CHERRY
}
Icon and Unicon
Nether Icon nor Unicon has an explicit enumeration type; however, there are several approaches that can be used for this purpose:
Inform 7
Fruit is a kind of value. The fruits are apple, banana, and cherry.
Inform 7 doesn't have conversions between enumerated values and numbers, but you can assign properties to enumerated values:
[sentence form]
Fruit is a kind of value. The fruits are apple, banana, and cherry.
A fruit has a number called numeric value.
The numeric value of apple is 1.
The numeric value of banana is 2.
The numeric value of cherry is 3.
[table form]
Fruit is a kind of value. The fruits are defined by the Table of Fruits.
Table of Fruits
fruit numeric value
apple 1
banana 2
cherry 3
J
J's typing system is fixed, and so extensions occur at the application level. For example, one could create an object
enum =: cocreate''
( (;:'apple banana cherry') ,L:0 '__enum' ) =: i. 3
cherry__enum
2
But this is more akin to a "methodless class or object" than an enum in other languages.
That said, note that the "natural way", in J, of dealing with issues treated in other languages through enums is to use an array of names.
fruit=: ;:'apple banana cherry'
Now you can get the name associated with an index:
2 { fruit
+------+
|cherry|
+------+
And you can get the index associated with a name:
fruit i.<'banana'
1
And you can define an arithmetic with the enum for its domain and range. Here, for example, is 2=1+1:
(<'banana') +&.(fruit&i.) <'banana'
+------+
|cherry|
+------+
And, you can iterate over the values, along with numerous other variations on these themes.
{{for_example. fruit do. echo;example end.}} ''
apple
banana
cherry
(A person could reasonably argue that enums were introduced in some languages to work around deficiencies in array handling in those languages. But this would be a part of a larger discussion about type systems and the use of systems of bit patterns to represent information.)
Java
enum Fruits{
APPLE, BANANA, CHERRY
}
Or:
enum Fruits{
APPLE(0), BANANA(1), CHERRY(2)
private final int value;
fruits(int value) { this.value = value; }
public int value() { return value; }
}
Conventionally, enums have the same case rules as classes, while enum values are in all caps (like other constants). All cases are allowed for both names, though, as long as they don't conflict with other classes in the same package.
JavaScript
In javascript, usually used for this a strings.
// enum fruits { apple, banana, cherry }
var f = "apple";
if(f == "apple"){
f = "banana";
}
jq
Finite, ordered enumerations can be represented in jq as JSON arrays, e.g. ["apple", "banana", "cherry"], or as sequences, e.g. ("apple", "banana", "cherry"). The latter interpretation corresponds to the idea of enumerating a collection, and also dovetails with the concept of infinite enumerations.
Countably-infinite ordered enumerations can be represented by generators, e.g. the non-negative natural numbers can be represented by the jq expression:
1 | while(true; .+1)
Finite, unordered enumerations can be represented as JSON objects, as in the JSON section of this article. In this context, it is worth noting that jq allows a shorthand notation for specifying objects, so that we can for example write:
def fruits: {apple, banana, cherry}; # i.e. {"apple" : null, "banana": null, "cherry": null }
JScript.NET
enum fruits { apple, banana, cherry }
enum fruits { apple = 0, banana = 1, cherry = 2 }
JSON
{"fruits" : { "apple" : null, "banana" : null, "cherry" : null }
{"fruits" : { "apple" : 0, "banana" : 1, "cherry" : 2 }
Julia
@enum Fruits APPLE BANANA CHERRY
- Output:
julia> Fruits Enum Fruits: APPLE = 0 BANANA = 1 CHERRY = 2
Kotlin
// version 1.0.5-2
enum class Animals {
CAT, DOG, ZEBRA
}
enum class Dogs(val id: Int) {
BULLDOG(1), TERRIER(2), WOLFHOUND(4)
}
fun main(args: Array<String>) {
for (value in Animals.values()) println("${value.name.padEnd(5)} : ${value.ordinal}")
println()
for (value in Dogs.values()) println("${value.name.padEnd(9)} : ${value.id}")
}
- Output:
CAT : 0 DOG : 1 ZEBRA : 2 BULLDOG : 1 TERRIER : 2 WOLFHOUND : 4
Lingo
Lingo neither knows the concept of enumerations nor of constants. But an enumeration-like hash (property list) that is immutable concerning standard list methods and operators can be created by sub-classing a property list and overwriting list/property list access methods (which also overwrites bracket access operators on the fly):
-- parent script "Enumeration"
property ancestor
on new (me)
data = [:]
repeat with i = 2 to the paramCount
data[param(i)] = i-1
end repeat
me.ancestor = data
return me
end
on setAt (me)
-- do nothing
end
on setProp (me)
-- do nothing
end
on deleteAt (me)
-- do nothing
end
on deleteProp (me)
-- do nothing
end
on addProp (me)
-- do nothing
end
enumeration = script("Enumeration").new("APPLE", "BANANA", "CHERRY")
put enumeration["BANANA"]
-- 2
-- try to change a value after construction (fails)
enumeration["BANANA"] = 666
put enumeration["BANANA"]
-- 2
-- try to change a value after construction using setProp (fails)
enumeration.setProp("BANANA", 666)
put enumeration["BANANA"]
-- 2
-- try to delete a value after construction (fails)
enumeration.deleteAt(2)
put enumeration["BANANA"]
-- 2
-- try to delete a value after construction using deleteProp (fails)
enumeration.deleteProp("BANANA")
put enumeration["BANANA"]
-- 2
-- try to add a new value after construction (fails)
enumeration["FOO"] = 666
put enumeration["FOO"]
-- <Void>
-- try to add a new value after construction using addProp (fails)
enumeration.addProp("FOO", 666)
put enumeration["FOO"]
-- <Void>
Lua
An explicit enum can be formed by mapping strings to numbers
local fruit = {apple = 0, banana = 1, cherry = 2}
or simply by local variables.
local apple, banana, cherry = 0,1,2
Although since Lua strings are interned, there is as much benefit to simply using strings.
M2000 Interpreter
Module Checkit {
\\ need revision 15, version 9.4
Enum Fruit {apple, banana, cherry}
Enum Fruit2 {apple2=10, banana2=20, cherry2=30}
Print apple, banana, cherry
Print apple2, banana2, cherry2
Print Len(apple)=0
Print Len(banana)=1
Print Len(cherry)=2
Print Len(cherry2)=2, Cherry2=30, Type$(Cherry2)="Fruit2"
k=each(Fruit)
While k {
\\ name of variable, value, length from first (0, 1, 2)
Print Eval$(k), Eval(k), k^
}
m=apple
Print Eval$(m)="apple"
Print Eval(m)=m
m++
Print Eval$(m)="banana"
Try {
\\ error, m is an object
m=100
}
Try {
\\ error not the same type
m=apple2
}
Try {
\\ read only can't change
apple2++
}
m++
Print Eval$(m)="cherry", m
k=Each(Fruit2 end to start)
While k {
Print Eval$(k), Eval(k) , k^
CheckByValue(Eval(k))
}
m2=apple2
Print "-------------------------"
CheckByValue(m2)
CheckByReference(&m2)
Print m2
Sub CheckByValue(z as Fruit2)
Print Eval$(z), z
End Sub
Sub CheckByReference(&z as Fruit2)
z++
Print Eval$(z), z
End Sub
}
Checkit
M4
define(`enums',
`define(`$2',$1)`'ifelse(eval($#>2),1,`enums(incr($1),shift(shift($@)))')')
define(`enum',
`enums(1,$@)')
enum(a,b,c,d)
`c='c
- Output:
c=3
Mathematica/Wolfram Language
Enumerations are not very useful in a symbolic language like Mathematica. If desired, an 'enum' function could be defined :
MapIndexed[Set, {A, B, F, G}]
->{{1}, {2}, {3}, {4}}
A
->{1}
B
->{2}
G
->{4}
MATLAB / Octave
Enumeration is done by creating a cell array (a.k.a set) of objects, where the numeral of the object is its index in the 1-based cell array. The cell array structure can contain any type of data structure including other cell arrays, and all members don't have to be the same data type.
Example:
stuff = {'apple', [1 2 3], 'cherry',1+2i}
stuff =
'apple' [1x3 double] 'cherry' [1.000000000000000 + 2.000000000000000i]
Metafont
Metafont has no an enumeration type. However we can define an useful macro to simulate an enumeration. E.g.
vardef enum(expr first)(text t) =
save ?; ? := first;
forsuffixes e := t: e := ?; ?:=?+1; endfor
enddef;
Usage example:
enum(1, Apple, Banana, Cherry);
enum(5, Orange, Pineapple, Qfruit);
show Apple, Banana, Cherry, Orange, Pineapple, Qfruit;
end
Modula-3
TYPE Fruit = {Apple, Banana, Cherry};
The values are accessed by qualifying their names.
fruit := Fruit.Apple;
You can get an element's position in the enumeration by using ORD
and get the element given the position by using VAL
.
ORD(Fruit.Apple); (* Returns 0 *)
VAL(0, Fruit); (* Returns Fruit.Apple *)
Nemerle
enum Fruit {
|apple
|banana
|cherry
}
enum Season {
|winter = 1
|spring = 2
|summer = 3
|autumn = 4
}
Nim
# Simple declaration.
type Fruits1 = enum aApple, aBanana, aCherry
# Specifying values (accessible using "ord").
type Fruits2 = enum bApple = 0, bBanana = 2, bCherry = 5
# Enumerations with a scope which prevent name conflict.
type Fruits3 {.pure.} = enum Apple, Banana, Cherry
type Fruits4 {.pure.} = enum Apple = 3, Banana = 8, Cherry = 10
var x = Fruits3.Apple # Need to qualify as there are several possible "Apple".
# Using vertical presentation and specifying string representation.
type Fruits5 = enum
cApple = "Apple"
cBanana = "Banana"
cCherry = "Cherry"
echo cApple # Will display "Apple".
# Specifying values and/or string representation.
type Fruits6 = enum
Apple = (1, "apple")
Banana = 3 # implicit name is "Banana".
Cherry = "cherry" # implicit value is 4.
Objeck
enum Color := -3 {
Red,
White,
Blue
}
enum Dog {
Pug,
Boxer,
Terrier
}
Objective-C
With iOS 6+ SDK / Mac OS X 10.8+ SDK:
typedef NS_ENUM(NSInteger, fruits) { apple, banana, cherry };
typedef NS_ENUM(NSInteger, fruits) { apple = 0, banana = 1, cherry = 2 };
OCaml
type fruit =
| Apple
| Banana
| Cherry
Odin
package main
Fruit :: enum {
Apple,
Banana,
Cherry,
}
FruitWithNumber :: enum {
Strawberry = 0,
Pear = 27,
}
main :: proc() {
b := Fruit.Banana
assert(int(b) == 1) // Enums always have implicit values
p := FruitWithNumber.Pear
assert(int(p) == 27)
}
Oforth
In Oforth, you use symbols to define enumerations.Symbols are strings that are identical : if two symbols are equal (==), they are the same object.
You can't define explicit values for these symbols as they a themseelves values.
Symbols begin with $. If the symbol does not exists yet, it is created.
[ $apple, $banana, $cherry ] const: Fruits
Ol
Ol enumerations is an builtin "ff"s as a simple fast dictionaries with number, constant or symbol keys and any typed values.
(define fruits '{
apple 0
banana 1
cherry 2})
; or
(define fruits {
'apple 0
'banana 1
'cherry 2})
; getting enumeration value:
(print (get fruits 'apple -1)) ; ==> 0
; or simply
(print (fruits 'apple)) ; ==> 0
; or simply with default (for non existent enumeration key) value
(print (fruits 'carrot -1)) ; ==> -1
; simple function to create enumeration with autoassigning values
(define (make-enumeration . args)
(fold (lambda (ff arg i)
(put ff arg i))
#empty
args
(iota (length args))))
(print (make-enumeration 'apple 'banana 'cherry))
; ==> '#ff((apple . 0) (banana . 1) (cherry . 2))
OxygenBasic
enum fruits
apple
pear
orange = 14
banana
mango
end enum
print banana '15
'fruits values:
' apple 0
' pear 1
' orange 14
' banana 15
' mango 16
Oz
Most of the time you will just use atoms where you would use enums in C. Atoms start with a lower-case letter and are just symbols that evaluate to themselves. For example:
declare
fun {IsFruit A}
{Member A [apple banana cherry]}
end
in
{Show {IsFruit banana}}
If you need constants with increasing values, you could just enumerate them manually:
declare
Apple = 1
Banana = 2
Cherry = 3
Or you could write a procedure that does the job automatically:
declare
proc {Enumeration Xs}
Xs = {List.number 1 {Length Xs} 1}
end
[Apple Banana Cherry] = {Enumeration}
in
{Show Cherry}
Pascal
Standard Pascal as per ISO 7185 only allows contiguous lists of identifiers as enumerated type definitions. An explicit index may not be specified, but Delphi and Free Pascal allow this. However, it is guaranteed, that the ordinal value will correspond to the member’s position in the list (0-based).
type
phase = (red, green, blue);
Perl
# Using an array
my @fruits = qw(apple banana cherry);
# Using a hash
my %fruits = ( apple => 0, banana => 1, cherry => 2 );
Phix
enum apple, banana, orange enum apple=5, banana=10, orange=
PHP
// Using an array/hash
$fruits = array( "apple", "banana", "cherry" );
$fruits = array( "apple" => 0, "banana" => 1, "cherry" => 2 );
// If you are inside a class scope
class Fruit {
const APPLE = 0;
const BANANA = 1;
const CHERRY = 2;
}
// Then you can access them as such
$value = Fruit::APPLE;
// Or, you can do it using define()
define("FRUIT_APPLE", 0);
define("FRUIT_BANANA", 1);
define("FRUIT_CHERRY", 2);
Picat
Picat doesn't have enumerations but they can be simulated by facts.
fruit(apple,1).
fruit(banana,2).
fruit(cherry,4).
print_fruit_name(N) :-
fruit(Name,N),
printf("It is %w\nn", Name).
PicoLisp
Enumerations are not very useful in a symbolic language like PicoLisp. If desired, an 'enum' function could be defined:
(de enum "Args"
(mapc def "Args" (range 1 (length "Args"))) )
And used in this way:
: (enum A B C D E F)
-> F
: A -> 1 : B -> 2 : F -> 6
PL/I
define ordinal animal (frog, gnu, elephant, snake);
define ordinal color (red value (1), green value (3), blue value (5));
PowerShell
Without explicit values.
Enum fruits {
Apple
Banana
Cherry
}
[fruits]::Apple
[fruits]::Apple + 1
[fruits]::Banana + 1
Output:
Apple Banana Cherry
With explicit values.
Enum fruits {
Apple = 10
Banana = 15
Cherry = 30
}
[fruits]::Apple
[fruits]::Apple + 1
[fruits]::Banana + 1
Apple 11 16
Prolog
Prolog doesn't have enums, but they can be simulated using a set of facts.
fruit(apple,1).
fruit(banana,2).
fruit(cherry,4).
write_fruit_name(N) :-
fruit(Name,N),
format('It is a ~p~n', Name).
PureBasic
Basic Enumeration is defined as
Enumeration
#Apple
#Banana
#Cherry
EndEnumeration
This can also be adjusted to the form
Enumeration 10200 Step 12
#Constant1 ; 10200
#Constant2 ; 10212
#Constant3 ; 10224
#Constant4 = 10117 ; 10117
#Constant5 ; 10229
EndEnumeration
The system constant "#PB_Compiler_EnumerationValue" holds last defined value and can be used to chain to a previously started series.
E.g. in combination with the code above;
Enumeration #PB_Compiler_EnumerationValue
#Constant_A ; 10241
#Constant_B ; 10242
EndEnumeration
Enumeration groups can also be named to allow continuation where a previous named group left off.
;This starts the enumeration of a named group 'NamedGroup'.
Enumeration NamedGroup 5
#Green ; 5
#Orange ; 6
EndEnumeration
;EnumerationBinary will use values that are a double of the previous value (or starting value).
EnumerationBinary
#North ; 1
#West ; 2
#South ; 4
#East ; 8
EndEnumeration
;This continues the enumeration of the previously named group 'NamedGroup'.
Enumeration NamedGroup
#Yellow ; 7
#Red ; 8
EndEnumeration
Python
Python: Version 3.4+
Note: enumerations have come to Python version 3.4.
>>> from enum import Enum
>>> Contact = Enum('Contact', 'FIRST_NAME, LAST_NAME, PHONE')
>>> Contact.__members__
mappingproxy(OrderedDict([('FIRST_NAME', <Contact.FIRST_NAME: 1>), ('LAST_NAME', <Contact.LAST_NAME: 2>), ('PHONE', <Contact.PHONE: 3>)]))
>>>
>>> # Explicit
>>> class Contact2(Enum):
FIRST_NAME = 1
LAST_NAME = 2
PHONE = 3
>>> Contact2.__members__
mappingproxy(OrderedDict([('FIRST_NAME', <Contact2.FIRST_NAME: 1>), ('LAST_NAME', <Contact2.LAST_NAME: 2>), ('PHONE', <Contact2.PHONE: 3>)]))
>>>
Python: Pre version 3.4
There is no special syntax, typically global variables are used with range:
FIRST_NAME, LAST_NAME, PHONE = range(3)
Alternately, the above variables can be enumerated from a list with no predetermined length.
vars().update((key,val) for val,key in enumerate(("FIRST_NAME","LAST_NAME","PHONE")))
R
R does not have an enumeration type, though factors provide a similar functionality.
factor(c("apple", "banana", "cherry"))
# [1] apple banana cherry
# Levels: apple banana cherry
This thread in the R mail archive contains code for an enum-like class for traffic light colours.
Racket
#lang racket
;; Like other Lisps, Racketeers prefer using symbols directly instead of
;; numeric definitions, and lists of symbols instead of bitwise
;; combinations
(define fruits '(apple banana cherry))
;; In Typed Racket, a type can be defined for a specific set of symbols
;; (define-type Fruit (U 'apple 'banana 'cherry))
;; The conventional approach is possible too, of course
(define APPLE 1)
(define BANANA 2)
(define CHERRY 4)
;; And finally, when dealing with foreign functions it is useful to
;; translate idiomatic Racket values (= symbols) to/from integers.
;; Racket's ffi has two ways to do this -- either an enumeration (for
;; independent integer constants) or a bitmask (intended to represent
;; sets using bitwise or):
(require ffi/unsafe)
(define _fruit (_enum '(APPLE = 1
BANANA
CHERRY = 4)))
(define _fruits (_bitmask '(APPLE = 1
BANANA = 2
CHERRY = 4)))
;; Normally, Racket code will just use plain values (a symbol for the
;; first, and a list of symbols for the second) and the foreign side
;; sees the integers. But do demonstrate this, we can use the primitive
;; raw functionality to see how the translation works:
(require (only-in '#%foreign ctype-scheme->c ctype-c->scheme))
((ctype-scheme->c _fruit) 'CHERRY) ; -> 4
((ctype-scheme->c _fruits) 'CHERRY) ; -> 4
((ctype-scheme->c _fruits) '(APPLE CHERRY)) ; -> 5
((ctype-c->scheme _fruit) 4) ; -> 'CHERRY
((ctype-c->scheme _fruits) 4) ; -> '(CHERRY)
((ctype-c->scheme _fruits) 5) ; -> '(APPLE CHERRY)
Raku
(formerly Perl 6)
enum Fruit <Apple Banana Cherry>; # Numbered 0 through 2.
enum ClassicalElement (
Earth => 5,
'Air', # gets the value 6
'Fire', # gets the value 7
Water => 10,
);
Raven
{ 'apple' 0 'banana' 1 'cherry' 2 } as fruits
Retro
Retro has a library named enum' for creation of enumerated values.
'/examples/enum.retro include
{ 'a=10 'b 'c 'd=998 'e 'f } a:enum
REXX
REXX has no types, and therefore has no enumeration type.
However, in the spirit of enumeration, REXX programmers can use stemmed arrays for enumerating constants (shown below).
This REXX entry was kinda modeled after the BASIC, Forth, and
VBA [which does its own enumeration, as does REXX below (as an inventory count)].
/*REXX program illustrates a method of enumeration of constants via stemmed arrays. */
fruit.=0 /*the default for all possible "FRUITS." (zero). */
fruit.apple = 65
fruit.cherry = 4
fruit.kiwi = 12
fruit.peach = 48
fruit.plum = 50
fruit.raspberry = 17
fruit.tomato = 8000
fruit.ugli = 2
fruit.watermelon = 0.5 /*◄─────────── could also be specified as: 1/2 */
/*A method of using a list (of some fruits).*/
@fruits= 'apple apricot avocado banana bilberry blackberry blackcurrant blueberry baobab',
'boysenberry breadfruit cantaloupe cherry chilli chokecherry citron coconut',
'cranberry cucumber currant date dragonfruit durian eggplant elderberry fig',
'feijoa gac gooseberry grape grapefruit guava honeydew huckleberry jackfruit',
'jambul juneberry kiwi kumquat lemon lime lingenberry loquat lychee mandarin',
'mango mangosteen nectarine orange papaya passionfruit peach pear persimmon',
'physalis pineapple pitaya pomegranate pomelo plum pumpkin rambutan raspberry',
'redcurrant satsuma squash strawberry tangerine tomato ugli watermelon zucchini'
/*╔════════════════════════════════════════════════════════════════════════════════════╗
║Parental warning: sex is discussed below: PG─13. Most berries don't have "berry" in║
║their name. A berry is a simple fruit produced from a single ovary. Some true ║
║berries are: pomegranate, guava, eggplant, tomato, chilli, pumpkin, cucumber, melon,║
║and citruses. Blueberry is a false berry; blackberry is an aggregate fruit; ║
║and strawberry is an accessory fruit. Most nuts are fruits. The following aren't║
║true nuts: almond, cashew, coconut, macadamia, peanut, pecan, pistachio, and walnut.║
╚════════════════════════════════════════════════════════════════════════════════════╝*/
/* ┌─◄── due to a Central America blight in 1922; it was*/
/* ↓ called the Panama disease (a soil─borne fungus)*/
if fruit.banana=0 then say "Yes! We have no bananas today." /* (sic) */
if fruit.kiwi \=0 then say "We gots " fruit.kiwi ' hairy fruit.' /* " */
if fruit.peach\=0 then say "We gots " fruit.peach ' fuzzy fruit.' /* " */
maxL=length(' fruit ') /*ensure this header title can be shown*/
maxQ=length(' quantity ') /* " " " " " " " */
say
do p =0 for 2 /*the first pass finds the maximums. */
do j=1 for words(@fruits) /*process each of the names of fruits. */
@=word(@fruits, j) /*obtain a fruit name from the list. */
#=value('FRUIT.'@) /* " the quantity of a fruit. */
if \p then do /*is this the first pass through ? */
maxL=max(maxL, length(@)) /*the longest (widest) name of a fruit.*/
maxQ=max(maxQ, length(#)) /*the widest width quantity of fruit. */
iterate /*j*/ /*now, go get another name of a fruit. */
end
if j==1 then say center('fruit', maxL) center("quantity", maxQ)
if j==1 then say copies('─' , maxL) copies("─" , maxQ)
if #\=0 then say right( @ , maxL) right( # , maxQ)
end /*j*/
end /*p*/
/*stick a fork in it, we're all done. */
output
Yes! We have no bananas today. We gots 12 hairy fruit. We gots 48 fuzzy fruit. fruit quantity ──────────── ────────── apple 65 cherry 4 kiwi 12 peach 48 plum 50 raspberry 17 tomato 8000 ugli 2 watermelon 0.5
Ring
apple = 0
banana = 1
cherry = 2
see "apple : " + apple + nl
see "banana : " + banana + nl
see "cherry : " + cherry + nl
Ruby
There are plenty of ways to represent enum in Ruby. Here it is just one example:
module Fruits
APPLE = 0
BANANA = 1
CHERRY = 2
end
# It is possible to use a symbol if the value is unrelated.
FRUITS = [:apple, :banana, :cherry]
val = :banana
FRUITS.include?(val) #=> true
To give a number in turn, there is the following method.
module Card
# constants
SUITS = %i(Clubs Hearts Spades Diamonds)
SUIT_VALUE = SUITS.each_with_index.to_h # version 2.1+
# SUIT_VALUE = Hash[ SUITS.each_with_index.to_a ] # before it
#=> {:Clubs=>0, :Hearts=>1, :Spades=>2, :Diamonds=>3}
PIPS = %i(2 3 4 5 6 7 8 9 10 Jack Queen King Ace)
PIP_VALUE = PIPS.each.with_index(2).to_h # version 2.1+
# PIP_VALUE = Hash[ PIPS.each.with_index(2).to_a ] # before it
#=> {:"2"=>2, :"3"=>3, :"4"=>4, :"5"=>5, :"6"=>6, :"7"=>7, :"8"=>8, :"9"=>9, :"10"=>10, :Jack=>11, :Queen=>12, :King=>13, :Ace=>14}
end
Rust
enum Fruits {
Apple,
Banana,
Cherry
}
enum FruitsWithNumbers {
Strawberry = 0,
Pear = 27,
}
fn main() {
// Access to numerical value by conversion
println!("{}", FruitsWithNumbers::Pear as u8);
}
Scala
1. Using Algebraic Data Types:
sealed abstract class Fruit
case object Apple extends Fruit
case object Banana extends Fruit
case object Cherry extends Fruit
2. Using scala.Enumeration:
object Fruit extends Enumeration {
val Apple, Banana, Cherry = Value
}
Scheme
(define apple 0)
(define banana 1)
(define cherry 2)
(define (fruit? atom)
(or (equal? 'apple atom)
(equal? 'banana atom)
(equal? 'cherry atom)))
(This section needs attention from someone familiar with Scheme idioms.)
Using syntax extension
The Implementation
; Syntax that implements a C-like enum; items without assignment take next value.
; Form: (enum <name> <item>...)
; Where <name> is a symbol that will be the name of the enum; <item> are one or
; more expressions that are either symbols or lists of symbol and integer value.
; The symbols are bound to the values. If a value is not given, then the next
; integer after the one bound to the previous symbol is used (starting at 0).
; The <name> itself is bound to an a-list of the item symbols and their values.
(define-syntax enum
(lambda (x)
(syntax-case x ()
((_ name itm1 itm2 ...)
(identifier? (syntax name))
(syntax
(begin
(define name '())
(enum-help name 0 itm1 itm2 ...)))))))
; Helper for (enum) syntax, above. Do not call directly!
(define-syntax enum-help
(lambda (x)
(syntax-case x ()
((_ name nxint)
(syntax (void)))
((_ name nxint (sym val) rest ...)
(and (identifier? (syntax sym))
(integer? (syntax-object->datum (syntax val))))
(syntax
(begin
(define sym val)
(set! name (cons (cons 'sym val) name))
(enum-help name (1+ val) rest ...))))
((_ name nxint sym rest ...)
(identifier? (syntax sym))
(syntax
(begin
(define sym nxint)
(set! name (cons (cons 'sym nxint) name))
(enum-help name (1+ nxint) rest ...)))))))
Example Use
(define-syntax test
(syntax-rules ()
((_ e)
(printf "~a --> ~s~%" 'e e))))
(printf "~%The 'foo' enum:~%")
(enum foo a (b 10) c (d 20) e (f 30) g)
(test a)
(test b)
(test c)
(test d)
(test e)
(test f)
(test g)
(test foo)
(test (assq 'd foo))
(test (assq 'm foo))
(printf "~%The 'bar' enum:~%")
(enum bar x y (z 99))
(test x)
(test y)
(test z)
(test bar)
- Output:
The 'foo' enum: a --> 0 b --> 10 c --> 11 d --> 20 e --> 21 f --> 30 g --> 31 foo --> ((g . 31) (f . 30) (e . 21) (d . 20) (c . 11) (b . 10) (a . 0)) (assq 'd foo) --> (d . 20) (assq 'm foo) --> #f The 'bar' enum: x --> 0 y --> 1 z --> 99 bar --> ((z . 99) (y . 1) (x . 0))
Seed7
const type: fruits is new enum
apple, banana, cherry
end enum;
Shen
(tc +)
(datatype fruit
if (element? Fruit [apple banana cherry])
_____________
Fruit : fruit;)
Sidef
Implicit:
enum {Apple, Banana, Cherry}; # numbered 0 through 2
Explicit:
enum {
Apple=3,
Banana, # gets the value 4
Cherry="a",
Orange, # gets the value "b"
};
Slate
As just unique objects:
define: #Fruit &parents: {Cloneable}.
Fruit traits define: #Apple -> Fruit clone.
Fruit traits define: #Banana -> Fruit clone.
Fruit traits define: #Cherry -> Fruit clone.
As labels for primitive values:
define: #Apple -> 1.
define: #Banana -> 2.
define: #Cherry -> 3.
As a namespace:
ensureNamespace: #fruit &slots: {#Apple -> 1. #Banana -> 2. #Cherry -> 3}.
Using a dictionary:
define: #fruit &builder: [{#Apple -> 1. #Banana -> 2. #Cherry -> 3} as: Dictionary].
Standard ML
datatype fruit =
Apple
| Banana
| Cherry
Swift
enum Fruit {
case Apple
case Banana
case Cherry
}
// or
enum Fruit {
case Apple, Banana, Cherry
}
enum Season : Int {
case Winter = 1
case Spring = 2
case Summer = 3
case Autumn = 4
}
Tcl
It is normal in Tcl to use strings from a set directly rather than treating them as an enumeration, but enumerations can be simulated easily. The following elegant example comes straight from the [Tcl wiki:]
proc enumerate {name values} {
interp alias {} $name: {} lsearch $values
interp alias {} $name@ {} lindex $values
}
it would be used like this:
enumerate fruit {apple blueberry cherry date elderberry}
fruit: date
# ==> prints "3"
fruit@ 2
# ==> prints "cherry"
Toka
Toka has no data types, and therefore no actual enumeration type. There is an optional library function which does provide a way to create enumerated values easily though.
This library function takes a starting value and a list of names as shown in the example below.
needs enum
0 enum| apple banana carrot |
10 enum| foo bar baz |
VBA
Like Visual Basic .NET, actually:
'this enumerates from 0
Enum fruits
apple
banana
cherry
End Enum
'here we use our own enumeration
Enum fruits2
pear = 5
mango = 10
kiwi = 20
pineapple = 20
End Enum
Sub test()
Dim f As fruits
f = apple
Debug.Print "apple equals "; f
Debug.Print "kiwi equals "; kiwi
Debug.Print "cherry plus kiwi plus pineapple equals "; cherry + kiwi + pineapple
End Sub
- Output:
test apple equals 0 kiwi equals 20 cherry plus kiwi plus pineapple equals 42
Visual Basic .NET
' Is this valid?!
Enum fruits
apple
banana
cherry
End Enum
' This is correct
Enum fruits
apple = 0
banana = 1
cherry = 2
End Enum
Wren
Wren doesn't support either enums or constants as such but a common way to indicate that a variable should not be mutated is to give it an upper case name and to group related variables together.
The only way to give such a variable a value without setting it explicitly is to add one to the previous such variable which (in effect) is what a C-style enum does. If you declare a variable in Wren without giving it a value, then it is set to the special value null which is no help here.
var APPLE = 1
var ORANGE = 2
var PEAR = 3
var CHERRY = 4
var BANANA = CHERRY + 1
var GRAPE = BANANA + 1
System.print([APPLE, ORANGE, PEAR, CHERRY, BANANA, GRAPE])
- Output:
[1, 2, 3, 4, 5, 6]
It is also possible to create an enum-like class using read-only static properties to get the values. The following code creates such a class dynamically at runtime. Note that the convention in Wren is for properties to begin with a lower-case letter.
import "./dynamic" for Enum
var Fruit = Enum.create("Fruit", ["apple", "orange", "pear", "cherry", "banana", "grape"], 1)
System.print(Fruit.orange)
System.print(Fruit.members[Fruit.cherry - 1])
- Output:
2 cherry
XPL0
def \Fruit\ Apple, Banana, Cherry; \Apple=0, Banana=1, Cherry=2
def Apple=1, Banana=2, Cherry=4;
Z80 Assembly
With Explicit Values
You can use labels to "name" any numeric value, whether it represents a constant or a memory location is up to the programmer. Code labels are automatically assigned a value based on what memory location they are assembled to.
Keep in mind that these names do not exist at runtime and are just for the programmer's convenience. None of this "code" below actually takes up any space in the assembled program.
Sunday equ 0
Monday equ 1
Tuesday equ 2
Wednesday equ 3
Thursday equ 4
Friday equ 5
Saturday equ 6
Without Explicit Values
A lookup table is the most common method of enumeration of actual data in assembly. Each element of the table can be accessed by an index, and the starting index is zero. (The index may need to be adjusted for data sizes larger than 1 byte, i.e. doubled for 16-bit data and quadrupled for 32-bit data.) Unlike the above example, these values do indeed take up memory. Using this method when the above enumeration would suffice is incredibly wasteful.
align 8 ;aligns "Days_Of_The_Week" to the next 256-byte boundary. The low byte of "Sunday" will be at memory location &XX00.
;this simplifies the lookup process significantly.
Days_Of_The_Week:
word Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
Sunday:
byte "Sunday",0
Monday:
byte "Monday",0
Tuesday:
byte "Tuesday",0
Wednesday:
byte "Wednesday",0
Thursday:
byte "Thursday",0
Friday:
byte "Friday",0
Saturday:
byte "Saturday",0
;This example will load Friday.
ld hl,Days_Of_The_Week ;get base address of table. (Thanks to the align 8, we know that L = 0.)
ld a,5 ;0 = Sunday, 1 = Monday, ... 5 = Friday, 6 = Saturday
add a ;Multiply A by 2 (this is faster than SLA A. RLCA would have also worked here)
ld L,a ;since the table was page-aligned it is sufficient to load A directly into L to properly index the table.
ld e,(hl) ;get the low byte into E
inc hl ;increment HL to high byte
ld d,(hl) ;get the high byte into D
;now DE contains the pointer to "Friday"
ex de,hl ;my PrintString routine takes the pointer in HL as the argument so we need to swap DE with HL.
call PrintString ;prints a null-terminated string to the screen.
ret ;return to basic
- Output:
Friday
zkl
Enums as thing or type is not supported but they can be simulated by running code at parse time (ie modify the AST before the compiler compiles it).
const RGB_COLOR{ // put color names in a name space
const RED =0xf00;
const BLUE=0x0f0, GREEN = 0x00f;
const CYAN=BLUE + GREEN; // → 0x0ff
}
println(RGB_COLOR.BLUE);
- Output:
240
const X0=N; // --> 0
const A=N,B=N,C=N; // --> 1,2,3
const{ _n=-1; } // reset Enum, this should be a const space function
const X=N; // -->0
Since const space runs at a different time [vs compile space], you need to really careful if you mix the two [spaces]:
#continuing ...
z:=N; // -->2 NOT 1 as it is set AFTER Y (compile time vs parse time)
const Y=N; // -->1! because it is set before z
zonnon
module Enumerations;
type
Fruits = (apple,banana,cherry);
var
deserts,i: Fruits;
begin
deserts := Fruits.banana;
writeln("ord(deserts): ",integer(deserts):2);
for i := Fruits.apple to Fruits.cherry do
writeln(integer(i):2)
end
end Enumerations.
- Output:
ord(deserts): 1 0 1 2
- Programming Tasks
- Basic language learning
- 11l
- 6502 Assembly
- 68000 Assembly
- 8086 Assembly
- ACL2
- Ada
- ALGOL 68
- AmigaE
- Arturo
- ATS
- AutoHotkey
- AWK
- BASIC
- BaCon
- Bracmat
- C
- C sharp
- C++
- Clojure
- Common Lisp
- Computer/zero Assembly
- D
- Delphi
- Diego
- DWScript
- E
- EGL
- Elixir
- EMal
- Erlang
- F Sharp
- Factor
- Fantom
- Forth
- Fortran
- Free Pascal
- FreeBASIC
- FutureBasic
- Go
- Groovy
- Haskell
- Huginn
- Icon
- Unicon
- Inform 7
- J
- Java
- JavaScript
- Jq
- JScript.NET
- JSON
- Julia
- Kotlin
- Lingo
- Lua
- M2000 Interpreter
- M4
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- Metafont
- Modula-3
- Nemerle
- Nim
- Objeck
- Objective-C
- OCaml
- Odin
- Oforth
- Ol
- OxygenBasic
- Oz
- Pascal
- Perl
- Phix
- Phix/basics
- PHP
- Picat
- PicoLisp
- PL/I
- PowerShell
- Prolog
- PureBasic
- Python
- R
- Racket
- Raku
- Raven
- Retro
- REXX
- Ring
- Ruby
- Rust
- Scala
- Scheme
- Seed7
- Shen
- Sidef
- Slate
- Standard ML
- Swift
- Tcl
- Toka
- VBA
- Visual Basic .NET
- Wren
- Wren-dynamic
- XPL0
- Z80 Assembly
- Zkl
- Zonnon
- PARI/GP/Omit
- Maxima/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- ZX Spectrum Basic/Omit
- Axe/Omit
- Pages with too many expensive parser function calls