
-----------------------------------
Clayton
Tue Jun 20, 2006 3:49 pm

[Tutorial]Enum - Enumerated Types
-----------------------------------
Enumerated Values
I'm not going to pretend that I'm an expert on the subject, but i have done some research on them and I feel confident that I can explain to you how they work. :D

How it Works
Basically and enumerated type is a type with predefined items/elements in them. The code for one looks as such (dont freak out I will be going over it line by line).


type colours : enum (red, green, blue)
var c : colours := colours.green
var d : colours := succ (c)
var e : colours := pred (c)
put ord (c)
put ord (d)
put ord (e)


OK, I'm sure some of you are going "WTF?!?!", so let me explain. 

Declaring your Enumerated Type

First line:


type colours : enum (red, green, blue)


Now, if you've been following the Turing Walkthrough (you have right?), you will already know about types, if not however, i suggest you go take a look at the tutorial on types first. Now on to the code. Basically what this line has done is created the enumerated type colours and given it the predefined elements of red, green and blue. Note that you can have as many or as few values as you wish.

If you wish to find out which position the element you are looking for is in you simply have to make use of the ord function. Eg.


put ord(colours.red)


What will that put out you ask? Let's take a look:


0


So if you wish to find out what position the element is truly in just add 1 to the ordinal value to give you that elements position in the enumerated type.

On to lines 2-4 of the code.
Assigning values of Enumerated Types to Variables


var c : colours := colours.green
var d : colours := succ (c)
var e : colours := pred (c)


All this is doing is initializing the three variables c, d, and e to a value in our enumerated type colours. Note that when you assign a value to a varible its type has to be that of your enumberated type (eg. if your enumerated type is called foo, you variable type has to be foo in order to accept any value from the enumerated type foo).

Now I'm sure some of you are wondering what succ and pred do. succ gives a varible the value of an enumerated type succeed by one of a current variable (or hardcoded value if you wish), while pred does the opposite, it gives the predecessing value to a variable.

So what we have at the moment is a program with the enumerated type colours and three variables, c, d and e containing the values colours.green (green), colours.blue (blue) and colours.red (red) respectively. 

Output:

Now lets output our information to the screen:


1
2
0


Now lets see how we arrived at that shall we? First we have our simple put statements:


put ord(c)
put ord(d)
put ord(e)


Remember how i told you before that you can find position with ord? Well this is how. So all this is doing is ouputting the ordinal value of the values from our enumerated type. But what if we wanted to find out what the information that was contained was? Simple. Just output it using put.


put c
put d
put e



green
blue
red


Great, I know how to use them, but what can I do now?

Good question. Enumerated types can be a very helpful thing when it comes to arrays. Using them, you can have an easier time to identify certain elements of an array. This can be particularily helpful when it comes to things such as RPGs where you would usually have some sort of armour, weapon etc. So using our knowledge of enumerated types we can help keep track of our elements of the array.

Using the example from above (an RPG) you can do something like this:


type equipped : enum (armour, weapon, boots, shield)
var items : array 0..3 of string := init ("steel plating","longsword","elvenskin boots","gold shield")
put items(ord(equipped.shield))


In this way, we can more easily keep track of our arrays through the use of enumerated types and descriptive variable names. Note that this is very similiar to a hash, which in other language is like calling an element of an array through other means than an integer value.

Just remember that for some reason the people at holtsoft didnt want you using enumerated types in anything at all (eg. you cant use colours.red from our example for Draw.FillBox). But if you really wanted to do something like that you could create an enumerated type with color names for each of the 255 colors, and call them with their ordinal value if you absolutely nuts. Instead stick to the idea of using them as hashes and whatever you may see them as. :D

However I am not going to pretend to be an expert, so if you have anything to add, PM me with what you want me to add and I'll edit this tutorial.

In Closing


Well I hope that you learned something from this, and I hope to hear from you guys :D Good Luck.


UPDATES: Added in a part for potential usages, showed how the color example could work if you put in enough work

-----------------------------------
Cervantes
Tue Jun 20, 2006 7:21 pm


-----------------------------------
Very nice tutorial!

Some feedback:

(eg. you cant use colors.red from our example for Draw.FillBox)

You most certainly can. From your tutorial, ord (colours.red) returns 0. In Turing, colours are represented by integers. So in this case, colours.red = 0 = white. Well that's no good. But it is easily fixed by rearranging your colours enumerated type to get the order correct. In fact, it wouldn't surprise me if the 'constants' like "green" and "brightblue" actually come from an export unqualified* enumerated type.

* Export unqualified means that you do no not have to reference the container, but rather just the item. For example, you can type "green" rather than "colours.green", if colours is the enumerated type.


This is great theory, but it needs some examples. Where can we use enumerated types?

One example i with arrays. Enumerated types can be used in conjunction with arrays to almost create a hash, which is like an array except elements are referenced by a key which could be any value including strings, rather than ordered integers. Enumerated types with arrays let us reference elements of the array like this:

type equip : enum (weapon, shield, helmet, armour)
var my_equipment : array 0 .. 3 of string := init ("Sword", "Buckler", "Padded Leather Cap", "Chain Mail")
put my_equipment (equip.armour)

Chain Mail

Untested.

This means we don't have to remember that armour was the fourth element of the array, indexed with a 3. Using "equip.armour" makes our code a heck of a lot more understandable.


So if you wish to find out what position the element is truly in just add 1 to the ordinal value to give you that elements position in the enumerated type. 

Yes. That will tell you the position in terms of "This is the fourth element". However, Adding one no longer tells you the index, obviously. There is a good reason the index starts at zero. A lot of languages use 0 as the starting index for arrays (and other things). Since Turing allows us to choose the lower bounds of our array, we can choose 0 as the lower bounds to be consistent with this enum behaviour and with other languages.

+200 BITS as promised. More to come if you work these points into your tutorial.

-----------------------------------
TheOneTrueGod
Tue Jun 20, 2006 7:26 pm


-----------------------------------
Nice tutorial.  I've been using enumerated types for a little while now, and I can say that this would have been really helpful back when I started trying to learn them.

And yah, Cervantes, your code won't work :P


put my_equipment (equip.armour)
%Should be
put my_equipment (ord(equip.armour))


Is there any way to define an enumerated type (or any type for that matter) as export unqualified?[/code]

-----------------------------------
Cervantes
Tue Jun 20, 2006 7:34 pm


-----------------------------------

And yah, Cervantes, your code won't work :P


put my_equipment (equip.armour)
%Should be
put my_equipment (ord(equip.armour))


Whups. Thanks for pointing that out. +15 bits to you. :)



Is there any way to define an enumerated type (or any type for that matter) as export unqualified?
You don't define things as export unqualified. You can define things as pervasive, but that's a different story. Rather, you export things as export unqualified. 

I'm not sure of the syntax for exporting something as export unqualified only, but I know that to export something as both pervasive and export unqualified, you do:

export *.~foo

Where the * means pervasive. You might want to try

export ~foo

or

export .~foo

to export foo as  export unqualified.

-----------------------------------
TheOneTrueGod
Tue Jun 20, 2006 7:44 pm


-----------------------------------
Well, I tried it, and it works  :D 

module math
    export ~.Distance
    function Distance (x1, y1, x2, y2 : real) : real
        result ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) ** 0.5
    end Distance
end math

put Distance (100, 100, 200, 100)


(Its ~.foo)

Thanks Cervantes.

-----------------------------------
Clayton
Tue Jun 20, 2006 8:27 pm


-----------------------------------
Thank you Cervantes for the bits :) the changes that you have suggested have been included (is that what you wanted? you will have to read through to check :twisted:) I hope people will learn from this

-----------------------------------
Tony
Tue Jun 20, 2006 9:59 pm


-----------------------------------

So if you wish to find out what position the element is truly in just add 1 to the ordinal value to give you that elements position in the enumerated type. 
you should mention 0-index, instead of "add a magic constant to make this work" :wink: 

It's an impressive tutorial, additional +100Bits

-----------------------------------
wtd
Wed Dec 06, 2006 3:47 am


-----------------------------------
Sorry for necro-posting, but is it possible to write code like the following, in order to avoid the necessity to actually specify the bounds of the array?

type equip : enum (weapon, shield, helmet, armour)
var my_equipment : array equip of string := init ("Sword", "Buckler", "Padded Leather Cap", "Chain Mail")
put my_equipment (equip.armour)

-----------------------------------
[Gandalf]
Wed Dec 06, 2006 3:55 am


-----------------------------------
Yes it most certainly is.  Very nice. :)

-----------------------------------
Clayton
Wed Dec 06, 2006 8:44 am


-----------------------------------
very fancy wtd, this shall be worked into the tutorial :P

-----------------------------------
Tyr_God_Of_War
Fri Mar 27, 2009 1:23 pm

Re: [Tutorial]Enum - Enumerated Types
-----------------------------------

type equipped : enum (armour, weapon, boots, shield)
var items : array equipped of string := init ("steel plating","longsword","elvenskin boots","gold shield")
put items(equipped.shield)


"Array (key type) of (whats in the array)" works too.
