1. basic questions about enums and enum types

Dear euphorians,

I would appreciate your guidance on some things about enums that confuse me.

I understand the basic notion of an enum as a collection of named constants, where the value of each element is 1 greater than the value of its predecessor, eg:
enum ONE, TWO, THREE, FOUR (where the value of the elements is 1, 2, 3, 4)?

And i understand the notion that an individual element may be assigned a particular value, from which point subsequent elements automatically increment, eg:
enum ONE, TWO, TEN=10, ELEVEN, SIX=6, NEXT (ie 1, 2, 10, 11, 6, 7)

Is it correct to think, then, that if there were no enums in OEu we would have to write a series of constants with the corresponding values
constant MONDAY = 1, TUESDAY = 2, WEDNESDAY = 3... etc?

Is it correct to consider enums as a construction that is quicker and easier to code than writing separate constants, and that makes our intention clearer by grouping a series of logically related values?

When it comes to enum types, is it correct to think of them as a mechanism for ensuring that only certain values for individual elements are valid? The reference manual gives an example:
enum type color RED=4, GREEN=7, BLACK=1, BLUE=3, PINK=10 end type

Is this simply a way for us to ensure that the valid value for RED ('positional value' = 1), is 4; for PINK ('positional value' = 5) is 10, etc? I haven't used this in code yet, and i don't see just at the moment how it would be useful, but i assume it must be or it wouldn't be there - true? A simple example might help me 'get it'.

I don't understand the subsequent example in the manual:
enum type color RED, GREEN=7, BLACK=1, BLUE=3, PINK=10 end type
The values of the elements are said to be 1, 2, 1, 4, 5 Why does the 'positional value' of BLACK go back to 1? Why not 3, since it is the third element along? Again, perhaps a simple example here, will help me understand the significance of this.

Thank you for your help. (And for those folks celebrating a festive season at the moment, i hope it is a safe and happy one.)
alex

2. Re: basic questions about enums and enum types

being lazy here... I will just paste what Pete Lomax has said for Phix

There are a few small differences between oE and Phix on this (will have to work up a comparison sometime.)

_tom

Enum

An enum declaration can be used to define automatically-incrementing constants. The default behaviour is for the first item to be 1 and each subsequent item incremented by 1. An explict value may be specified for any item. Enums may currrently only take integer values (see below). Such values must always be numeric literals, as opposed to expressions or other variables or constants. Subsequent values default to the previous value plus one, unless they too are assigned a default value.

```enum ONE=1, TWO, THREE, ABC=10, DEF, XYZ
-- ONE is 1, TWO is 2, THREE is 3
-- ABC is 10, DEF is 11, XYZ is 12
```

Note that C enums start at 0 by default, and you should remember to specify "=0" on the first element when (manually) translating C to Phix, unless of course the enum is just being used to guarantee uniqueness and as such the actual values do not really matter.

It is not a bad idea to always explicitly specify the starting value of an enum, even if it is 1, to avoid confusing anyone more accustomed to the way enums behave in some other programming language.

As with other declarations, enums can be terminated with a \$ for ease of editing enum lists that change frequently during development.

```enum
YES,
NO,
--  MAYBE,
--  EITHER,
--  SOMETIMES,
OFTEN,
--  RARELY,
\$
<eucode>

```

You can also use \$ to replicate the last value, eg

( =\$ syntax is Phix only )

```enum ONE,TWO,THREE,ALL=\$
?{ONE,TWO,THREE,ALL}            -- {1,2,3,3}
enum UN,UNO=\$,DUO,TRE,TRES=\$
?{UN,UNO,DUO,TRE,TRES}          -- {1,1,2,3,3}
```

Obviously attempts to use \$ on the very first enum trigger a compilation error ("no prior value").

Sequences use integer indexes, but with enum you may write code like this:

```enum X, Y
sequence point = { 0,0 }
point[X] = 3
point[Y] = 4
```

enum type

There is also a special form of enum, an enum type. This is a simple way to write a user-defined type based on the set of values in a specific enum group.

The type created this way can be used anywhere a normal user-defined type can be used.

```enum type RGBA RED, GREEN, BLUE, ALPHA end type
-- Only allow values of RED, GREEN, BLUE, or ALPHA as parameters
function xyz(RGBA x, RGBA y)
return
end function
```

The above enum statement is in fact (apart from the parameter being named "i") equivalent to:

```enum RED, GREEN, BLUE, ALPHA
type RGBA(integer i) return find(i,{RED, GREEN, BLUE, ALPHA}) end type
```

You may have spotted that there is one significant difference concerning enum types. Normal type functions return either 1 or 0, whereas enum type functions return a positive integer index when the argument is a member, or 0 if not.

The value returned is the ordinal number of the member in the enum definition, regardless of what the member value is. Should two enums share the same value, they will share the same ordinal number. The ordinal numbers of enums surrounding these continue to increment as if every enum had a unique ordinal number, causing some numbers to be skipped. Lastly, although only applicable for enum type routines that are likely to be invoked more than 106 times, it would be remiss of me not to mention that the use of find in enum types may be slower than say i>=RED and i<=ALPHA, especially for enum types with several dozen or a few hundred or maybe even thousands of elements, however it is no big deal to replace such with a faster explicit type much as above, should that be a significant concern.

```enum type color RED=4, GREEN=7, BLACK=1, BLUE=3 , PINK=10 end type
? color(RED)   -- 1
? color(GREEN) -- 2
? color(BLACK) -- 3
? color(BLUE)  -- 4
? color(PINK)  -- 5
constant color_names = {"rouge", "vert", "noir", "bleu", "rose"}
puts(1, color_names[color(BLUE)]) -- bleu
```

However if RED and BLACK were (for some unknown reason) given the same value:

```enum type color RED, GREEN=7, BLACK=1, BLUE=3 , PINK=10 end type
? color(RED)   -- 1
? color(GREEN) -- 2
? color(BLACK) -- 1
? color(BLUE)  -- 4
? color(PINK)  -- 5
```

Note that none of the enums have an ordinal number with a value of 3. This is simply skipped. Unless an enum member is being set to a specific value, it defaults to 1 more than the previous member.

This default increment can be overridden. The syntax is:

```enum [type name] by DELTA member1, member2, ... ,memberN
```

where 'DELTA' is a literal number with an optional +, -, or * operator preceding it. Also, for the same reasons that floating point for loops are prohibited, phix only supports integer enums, and hence only integer deltas, and is unlikely to ever support "by /N".

```enum by 2 A,B,C=6,D      -- values are 1,3,6,8
enum by * 2 A,B,C,D,E    -- values are 1,2,4,8,16
```

Should both be present, a "by amount" clause must follow rather than precede "type name".