                           CHAPTER 11 - Records


                      PREREQUISITES FOR THIS MATERIAL

             In order to do a profitable study of this material, you
        will  need  a good understanding of all of the  material  in
        Part  I.   The  material  concerning the  scalar  type  from
        chapter 11 is also needed.

            We  come  to  the grandaddy of all  data  structures  in
        Modula-2,  the RECORD.   A record is composed of a number of
        variables  any of which can be of any predefined data  type,
        including  other records.   Rather than spend time trying to
        define  a  record  in detail,  lets go right  to  the  first
        example  program,  SMALLREC.MOD.   This is a  program  using
        nonsense data that will illustrate the use of a record.

                           A VERY SIMPLE RECORD

            There is only one entry in the TYPE declaration part  of
        the program,  namely the record identified by "Description".
        The record is composed of three fields, the "Year", "Model",
        and  "Engine" variables.   Notice that the three fields  are
        each of a different type,  indicating that the record can be
        of  mixed types.   You have a complete example of the way  a
        record  is  defined  before  you.   It is  composed  of  the
        identifier "Description", the reserved word RECORD, the list
        of  elements,  and followed by END;.   Notice that this only
        defines a TYPE,  it does not define any variables.   That is
        done  in  the VAR declaration where the variable  "Cars"  is
        defined   to   have  10  complete  records   of   the   type
        "Description".  The variable "Cars[1]" has three components,
        "Year",  "Model",  and  "Engine",  and  any or all of  these
        components   can  be  used  to  store  data  pertaining   to
        "Cars[1]".

            In  order  to assign values to the various  fields,  the
        variable name is followed by the sub-field with a separating
        period.   Keep  in mind that "Cars[1]" is a complete  record
        containing three variables,  and to assign or use one of the
        variables,  you  must  designate  which  sub-field  you  are
        interested in.   See the program where the three fields  are
        assigned  meaningless  data for  illustration.   The  "Year"
        field  is  assigned  an  integer  number  varying  with  the
        subscript,   all   "Model"  fields  are  assigned  the  name
        "Duesenburg",  and  all "Engine" variables are assigned  the
        value "V8".   In order to further illustrate that there  are
        actually  30  variables in use here,  a few are  changed  at
        random  in  the next few statements,  being very careful  to
        maintain   the  required  types  as  defined  in  the   TYPE
        declaration part of the program.  Finally, all ten composite
        variables,  consisting  of 30 actual variables in a  logical
        grouping  are  printed  out using  the  same  "var.subfield"


                                  Page 65









                           CHAPTER 11 - Records


        notation described above.

            If the preceding description of a record is not clear in
        your mind,  review it very carefully.  It's a very important
        concept in Modula-2,  and you won't have a hope of a  chance
        of understanding the next example until this one is clear.

                              A SUPER RECORD

            Examine   the   example  file  BIGREC.MOD  for  a   very
        interesting  record.   First  we have  a  constant  defined.
        Ignore  it  for the moment,  we will come back to it  later.
        Within  the TYPE declaration we have three records  defined,
        and upon close examination,  you will notice that the  first
        two  records  are included as part of the definition of  the
        third record.   The record identified as "Person",  actually
        contains 8 variable definitions, three within the "FullName"
        record,  two of its own, and three within the "Date" record.
        This is a TYPE declaration and does not actually define  any
        variables, that is done in the VAR part of the program.

            The  VAR  part  of the program  defines  some  variables
        beginning  with the array of "Friend" containing 50 (because
        of  the  constant definition in the CONST part)  records  of
        "Person".   Since  "Person" defines 8 fields,  we  have  now
        defined  8  times 50 = 400 separate and distinct  variables.
        Each  of  the  400  separate  variables  has  its  own  type
        associated with it,  and the compiler will generate an error
        if  you try to assign any of those variables the wrong  type
        of  data.   Since "Person" is a TYPE definition,  it can  be
        used  to define more than one variable,  and in fact  it  is
        used again to define three more records,  "Self",  "Mother",
        and  "Father".   These three records are each composed of  8
        variables,  so  we  have  24  more variables  which  we  can
        manipulate within the program.  Finally we have the variable
        "Index" defined as a simple CARDINAL type variable.   Notice
        that if we desired,  we could also define a variable of type
        "FullName" composed of 3 simple variables.

                    HOW TO MANIPULATE ALL OF THAT DATA

            In  the program we begin by assigning data to all of the
        fields of "Self".   Examining the first three statements  of
        the main program,  we see the construction we learned in the
        last  example program being used,  namely the period between
        descriptor fields.   The main record is named "Self", and we
        are  interested  in the first part of it namely  the  "Name"
        part  of the person record.   Since the "Name" part  of  the
        person  record  is itself composed of three parts,  we  must
        designate  which  part  of it we  are  interested  in.   The
        complete  description "Self.Name.FirstName" is the  complete


                                  Page 66









                           CHAPTER 11 - Records


        description  of  the first name of "Self" and is  the  first
        assignment   statement  which  is  assigned  the   name   of
        "Charley".   The next two fields are handled in the same way
        and are self explanatory.

                        WHAT IS THE WITH STATEMENT?

            Continuing on to the fourth field, the "City", there are
        only  two  levels  required because "City"  is  not  another
        record definition.  The fourth field is therefore completely
        defined   by  "Self.City".    Notice  the  "WITH  Self   DO"
        statement.   This  is a shorthand notation used with  record
        definitions to simplify coding.   From the BEGIN at the next
        statement  to the matching END;  about 10 statements  later,
        any  variables  within the "Self" record are used as  though
        they had a "Self." in front of them.   It greatly simplifies
        coding to be able to omit the leading identifier within  the
        WITH  section  of  code.   You will  see  that  "City",  and
        "State",   are   easily  assigned  values  without   further
        reference to the "Self" variable.   When we get to the "Day"
        part  of the birthday,  we are back to three levels and  the
        complete  definition is "Self.Birthday.Day" but once  again,
        the  "Self." part is taken care of automatically because  we
        are still within the "WITH Self DO" area.

            To  illustrate  the WITH statement further,  another  is
        introduced,  "WITH Birthday DO",  and an area is defined  by
        the   BEGIN  END  pair.    Within  this  area  both  leading
        identifiers  are handled automatically to  simplify  coding,
        and  "Month" is equivalent to writing  "Self.Birthday.Month"
        if both WITH statements were removed.   You may be wondering
        how   many   levels  of  nesting  are  allowed   in   record
        definitions.   There  doesn't appear to be a limit according
        to the Modula-2 definition,  but we do get a hint at how far
        it is possible to go.   In most implementations of Modula-2,
        you  are  allowed  to have WITH statements  nested  to  nine
        levels,  and  it would be worthless to nest WITH  statements
        deeper  than the level of records.   Any  program  requiring
        more  levels  than nine is probably far beyond the scope  of
        your programming ability, and mine, for a long time.

            After assigning a value to the year,  the entire  record
        of "Self" is defined, all eight variables.

                        SUPER-ASSIGNMENT STATEMENTS

            The   next  statement,   "Mother  :=  Self;"   is   very
        interesting.   Since both of these are records, both are the
        same type of record, and both therefore contain 8 variables,
        Modula-2  is smart enough to recognize that,  and assign all
        eight  values  contained  in  "Self"  to  the  corresponding


                                  Page 67









                           CHAPTER 11 - Records


        variables of "Mother".   So after one statement, "Mother" is
        completely  defined.   The  next statement assigns the  same
        values  to the eight respective fields of "Father", and  the
        next  two  lines assign all 50 "Friend" variables  the  same
        data.   We have therefore generated 400 + 24 = 424  separate
        pieces  of data so far in this program.   We could print  it
        all out,  but since it is nonsense data, it would only waste
        time and paper.  The next three lines write out three sample
        pieces of the data for your inspection.

                         WHAT GOOD IS ALL OF THIS

            It should be obvious to you that what this program does,
        even  though  the  data  is  nonsense,  appears  to  be  the
        beginning of a database management program,  which indeed it
        is.  It is a crude beginning, and has a long way to go to be
        useful, but you should see a seed for a useful program.

            Now to go back to the CONST as promised.   The number of
        friends was defined as 50 and used for the size of the array
        and in the assignment loop near the end of the program.  You
        can  now edit this number and see how big this database  can
        become on your computer.  Your compiler should be capable of
        storing  about  1000 records even within the smallest  model
        available  on any compiler.  If your compiler uses a  larger
        memory model,  you will be able to store significantly  more
        records.   See  how  big you can make the number of  friends
        before you get the memory overflow message.  Keep the number
        in  mind because when we get to the chapter on Pointers  and
        Dynamic  Allocation,  you  should see a marked  increase  in
        allowable size, especially if you have a large amount of RAM
        installed  in your computer.   If your compiler uses a large
        memory model,  you won't see an increase in size but it will
        be an interesting exercise anyway.

                             A VARIANT RECORD

            If  any part of this chapter is still unclear,  it would
        be good for you to go back and review it at this time.   The
        next  example  will  really  tax  your  mind  to  completely
        understand  it,  especially  if the prior  material  is  not
        clear.

            Examine  the  program  VARREC.MOD for an  example  of  a
        program with a variant record definition.   In this example,
        we  first define a scalar type,  namely "KindOfVehicle"  for
        use  within  the record.   Then we have  a  record  defining
        "Vehicle",  intended  to  define several different types  of
        vehicles,  each with different kinds of data.   It would  be
        possible  to define all variables for all types of vehicles,
        but  it  would  be a waste of storage space  to  define  the


                                  Page 68









                           CHAPTER 11 - Records


        number  of  tires for a boat,  or the  number  of  propeller
        blades  used on a car or truck.   The variant record lets us
        define  the data precisely for each vehicle without  wasting
        data storage space.

                           WHAT IS A TAG-FIELD?

            In the record definition we have the usual RECORD header
        followed  by three variables defined in the same  manner  as
        the records in the last two example programs.   Then we come
        to the CASE statement.  Following this statement, the record
        is  different  for  each of the four types  defined  in  the
        associated  scalar definition.   The variable "WhatKind"  is
        called  the tag-field and must be defined as a  scalar  type
        prior  to  the  record definition.   The tag-field  is  what
        selects the variant used,  when the program uses one of  the
        variables with this record type.   The tag-field is followed
        by  a colon and its type definition,  then the reserved word
        OF.   A list of the variants is then given, with each of the
        variants  having  the  variables  for  its  particular  case
        defined.   The  list of variables for one variant is  called
        the field list.

            A few rules are in order at this point.  The variants do
        not have to have the same number of variables in each  field
        list,  and in fact,  one or more of the variants may have no
        variables  at all in its variant part.   If a variant has no
        variables, it must still be defined with a blank followed by
        a semi-colon.  All variables in the entire variant part must
        have unique names.   The three variables, "Wheels", "Tires",
        and "Tyres",  all mean the same thing to the user,  but they
        must  be different for the compiler.   You may use the  same
        identifiers again in other records and for simple  variables
        anywhere  else  in the program.   The Modula-2 compiler  can
        tell which variable you mean by its context.  Using the same
        variable  name  should  be discouraged  as  bad  programming
        practice because it may confuse you or another person trying
        to understand your program at a later date.

                         USING THE VARIANT RECORD

            We  properly define four variables with the record  type
        "Vehicle" and go on to examine the program itself.

            We  begin  by  defining  one of our  variables  of  type
        "Vehicle",  namely  the variable named  "Ford".   The  seven
        lines  assigning  values to "Ford" are similar to the  prior
        examples  with  the exception of the fourth  line.   In  the
        fourth  line  the  tag-field which  selects  the  particular
        variant used is set equal to the value "Truck",  which is  a
        scalar  definition,  not  a variable.   This means that  the


                                  Page 69









                           CHAPTER 11 - Records


        variables  named  "Motor",   "Tires",   and  "Payload"   are
        available for use with the record "Ford",  but the variables
        named "Wheels", "Engine", "Tyres", etc. are not available in
        the record named "Ford".

            Next,  lets  define the record "Sunfish" as a boat,  and
        define all of its variables.  All of sunfish's variables are
        defined but in a rather random order to illustrate that they
        need not be defined in a particular order.   Recall the  use
        of WITH from the last example program.

            To  go even further in randomly assigning the  variables
        to a record,  we redefine "Ford" as having an "Engine" which
        it  can only have if it is a car.   This is one of the  fine
        points  of  the record.   If you assign any of  the  variant
        variables,  the record is changed to that variant, but it is
        the  programmers responsibility to assign the  correct  tag-
        field  to  the record,  not the Modula-2  compiler's.   Good
        programming practice would be to assign the tag-field before
        assigning  any of the variant variables.   The remainder  of
        the  "Ford" variables are assigned to complete that  record,
        the non-variant part remaining from the last assignment.

            The  variable  "Mac"  is now set equal to  the  variable
        "Sunfish".   All  variables within the record are copied  to
        "Mac" including the tag-field, making "Mac" a boat.

                  NOW TO SEE WHAT WE HAVE IN THE RECORDS

            We  have  assigned "Ford" to be a  car,  and  two  boats
        exist,  namely  "Sunfish"  and "Mac".   Since "Schwinn"  was
        never defined,  it has no data in it,  and is at this  point
        useless.  The "Ford" tag-field has been defined as a car, so
        it should be true in the IF statement, and the first message
        should  print.   The "Sunfish" is not a bicycle,  so it will
        not  print.   The  "Mac" has been defined as a boat  in  the
        single assignment statement, so it will print a message with
        an  indication  that  all  of the data  in  the  record  was
        transferred to its variables.

            Even  though  we  can make  assignment  statements  with
        records,  they cannot be used in any mathematical operations
        such as addition,  or multiplication.   They are simply used
        for data storage.   It is true however,  that the individual
        elements  in  a  record  can be  used  in  any  mathematical
        statements legal for their respective types.

            One other point should be mentioned.   The tag-field can
        be completely eliminated resulting in a "free union" variant
        record.   This  is  possible because Modula-2,  as  you  may
        remember  from above,  will automatically assign the variant


                                  Page 70









                           CHAPTER 11 - Records


        required when you assign data to one of the variables within
        a variant.  This is the reason that all variables within any
        of  the  variants must have unique names.   The  free  union
        record  should be avoided in your early programming  efforts
        because you cannot test a record to see what variant it  has
        been assigned to.

                        A NOTE TO PASCAL PROGRAMMERS

             A  record with a free union variant is commonly used in
        Pascal to do type transfers,  but this should be discouraged
        in Modula-2 since it has a complete set of carefully defined
        type transfer functions for that purpose.   In addition, the
        method  of  data storage is not specified as a part  of  the
        language  and  a free union would not operate the  same  way
        with  different  compilers if used for the purpose  of  type
        transfer.

                           PROGRAMMING EXERCISE

        1.  Write  a simple program with a record to store the names
            of five of your friends and display the names.































                                  Page 71
