Turing Records and Types
From Compsci.ca Wiki
Contents |
Wrecked Cords?
Records, incredibly useful thingies they are. Well, thingie isn't really the right definition for it. Here, why not begin with a description:
A record is like a composite data type. A record can consists of many fields, and each field may consist of different types of data of varying length. An example being:
type studentData: record firstname: string lastname: string height: real age: int grade: int passing: boolean end record
While C users may be familiar with records as [b]structures[/b] (or [b]struct[/b] for short), some of us have never seen this type of declaration before. Why bother to gathering together a bunch of data types that we already know how to use and put them into one big lump?
Jean Pockets Don't Make Good Pencil Cases.
While there are other reasons for it, records are incredibly useful as an organization tool. Why do you carry binders around in school? Why do you put your pens, pencils, erasers, rulers and straight edges all in a pencil case? You don't do it because your friends will laugh at you because you are not "cool" enough to have a pencil case (well, at least I hope that isn't the case). You do it because it's rather hard to keep track of all your writing utensils if you stick one in your jeans today and the other in your shirt pocket tomorrow. As programmers, we like to keep things clean and efficient. Concise coding can reduce runtime errors and debugging time, especially if multiple people were to look over the same code. As codes that only one person can understand are quite useless to other people, we try to code according to a "good"Â standard.
Using this knowledge, let's find a situation in which records can be well used.
Maybe an Example Will Help?
Suppose I opened an online dating service called "Love Bytes" (with plenty of financial backings from Mr. Mckenzie). This little online database system allows me to keep track of personal information from various clients. People especially seems to want to know about these details from potential suitors:
- First name
- Last name
- Gender
- Age
- Height
- Hair colour
- Love rating
Now I want to keep track of these information, so I prompt the user to input their personal data. Assuming I have no knowledge whatsoever of records, here is what I would have done:
var FirstName : string var LastName : string var Gender : char var Age : int var Ht : real var HColour : string var LRating : int put "What is your first name?" get FirstName put "What is your last name?" get LastName . . . put "Hello ", FirstName, " ", LastName, "." put "You are a ", Age, " year old " .. if Gender = 'm' or Gender = 'M' then put "male " .. else put "female " .. end if put "looking for a good time? Well you found the right place!"
Now this would get pretty tedious if there are let's say, 100 people's data to input. You would have to at least create a bunch of different arrays with 100 elements inside to hold the information.
var FirstName : array 1 .. 100 of string var LastName : array 1 .. 100 of string . . .
If you are still unfamiliar about arrays, I suggest you read up on the tutorial here at compsci.ca, since it is a very important part of programming.
So with an array of 100 elements, termed FirstName, I stored all the first names of the clients, and when I need to use these information, I will have to recall these names by finding the correct array and accessing the correct element. I don't know about you, but it gets really hard to keep track of everything when I have to code a large database program. I don't want to have to spend time looking back once so often to see if I missed Hcolour or forgot which element the index of the array refers to.
That wasn't a very efficient (or pretty) way of dealing with the coding. I wanted something more compact, so I learned about records. You will too, provide you look down for a couple of lines.
The Way of the Wrecking Cords
Like I say before, records are like You-Design-It data types. Tired of classifying variables as string or int? Well, you can now name a type after yourself (if you REALLY wanted to, why not?). The syntax for records looks like this:
type id : record id {,id} : typeSpec {id {,id} : typeSpec} end record
Now this may not be that useful to you, so let's put it into an example. We'll use our Love Bytes program from here.
Woot! Real Code!
type Client : record FirstName : string LastName : string Gender : char Age : int Ht : real HColour : string LRating : int end record var customers : Client put "What is your first name: " .. get customers.FirstName put "Hello ", customers.FirstName
Don't worry if something here doesn't make sense yet, we'll explain it all in due time.
What? Why Would I Want to Type the Word Client?
type Client :
First we'll name our new data type, since we are dealing with clients, we can just name the type [i]Client[/i]. You can name it PrezBush if you want (Republican pride? If you REALLY wanted, why not?). The compiler doesn't care about the name; it only helps the person reading the code to become less confused.
That's Alot of Stuff...
record FirstName : string LastName : string Gender : char Age : int Ht : real HColour : string LRating : int end record
We want everything we listed above to be included in our new data type, so the syntax dictates that we begin with record, and end with a end record, with every attributes sandwiched in between. Notice that when we are declaring the fields, we are not using var, this is because these aren't variables, rather they are predefined data type fields.
The field could be of any type. int, real, boolean, string, char, or even another self defined data type (we'll deal with this specific situation on the next tutorial).
Recording with Records
var customers : Client
Now we have defined our data type, time to declare some variables. Obviously we want to use what we've just created. In this instance, we create a variable called [i]customers[/i], of the type [i]Client[/i]. Remember that [i]Client[/i] is a custom data type that we created ourselves, at this point, it is just like [b]int[/b] or [b]string[/b], and has its own properties defined by us.
put "Please input your first name: " .. get customers.FirstName put "Hello ", customers.FirstName
We want to be able to use this variable right? So how do we store values into [i]customers[/i]? [i]Customers[/i] is accessed just like how normally declared variable are accessed. That is, with one exception: you have to identify the field you wish to access when you call the variable. Trying to operate directly on [i]customers[/i] will only result in an illegal action error. You can however, access the fields specified by our custom data type, just by typing the variable name plus a period plus the field. So to gain access to age, we use [i]customers.Age[/i], to gain access to the love rating, use [i]customers.LRating[/i]. So far, so good.
And that's it. No, seriously, that's all there is to it for the basic use of records. Oh, you want something more complicated? Well, first, answer these questions first, if you got these questions right, then by all means, go on to the next section.
Compsci Quiz of Doom!!!
Questions #1
Since Client is just another data type, that means I can create an array of Client. So I modified my program above just a little bit, this way, I can keep track of about 100 different clients at the same time.
type Client : record FirstName : string LastName : string Gender : char Age : int Ht : real HColour : string LRating : int end record var customers : array 1 .. 100 of Client put "What is your first name: " .. get customers.FirstName (1) put "Hello ", customers.FirstName (1)
Running it, the turing compiler tells me that 'customers' cannot be followed by a '.'
What? But I just told you that's how we access fields inside a record! Did I lie to you? What's wrong with this program?
- If you played around with the position of the index, you should have been able to figure it out. Since we declared an array from 1 to 100 of customers, the index should go after customers, not after FirstName. We should replace the erroneous part with customers (1).FirstName. Placing the index after FirstName has a totally different meaning.
Question #2
So you got the first question solved. What? You didn't? Well, hurry up and go back to it before looking at this one. All solved? Good, now that wasn't all that bad wasn't it? The second question involves the same scenario. Let's go back to the customers.FirstName (1) for a minute. I told you that placing the index of the array behind the field has a different meaning, basically it means now there is an array of FirstName. If we created our records to be like this:
type Client : record FirstName : array 1.. 2 of string . . . end record
then it would work.
The next question involves this: I don't know how many first names a person can have. He or she may have a English name, plus a name in his or her native language, plus some other shortened name that he or she wishes to use at all times. So I want to ask at the beginning how many names they wish to enter. I modified my program to look like the one below:
var num : int type Client : record FirstName : array 1 .. num of string LastName : string Gender : char Age : int Ht : real HColour : string LRating : int end record var customer : Client put "How many names do you wish to enter?" get num for i : 1 .. num put "What is your first name: " .. get customer.FirstName (i) end for
So I run this program, but of course an error pops up (it wouldn't be a question otherwise 8) ). "Compile time expression expected". Now what does that mean? What did I do wrong? Think about it for a couple of minutes. Once you think you got it, highlight below to see the answer.
- Straight out of Turing's help files on records: Any array contained in a record must have bounds that are known at compile time. So that's something we can't do. Whoa you mean to tell me we can't do something with a programming language? Well, technically, no, I'm not. Because there are ways to achieve what we wanted to do initially, you just don't know them yet. I suggest trying for yourself for a bit, and once you are confident in your handling of records, we can move on to the next section of this tutorial: Records Part II: enum, pointer, and other advanced concepts.
Hope this helped. See you next tutorial!
Credits
Author: AsianSensation Added by: Wtd