home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / modula2 / mod2txt.zip / CHAP5.TXT < prev    next >
Text File  |  1987-03-25  |  24KB  |  521 lines

  1.                      Chapter 5 - Modula-2 Procedures
  2.  
  3.  
  4.              In  order to define the procedure, we will need to  lay
  5.         some groundwork in the form of a few definitions.
  6.  
  7.         Program  Heading  - This  is the easiest part  since  it  is
  8.              only  one  line,  at least it has been in  all  of  our
  9.              programs  up  to this point.   It is simply the  MODULE
  10.              line,  and it never needs to be any more involved  than
  11.              it  has  been up to this point,  except for  one  small
  12.              addition which we will cover in a later chapter.
  13.  
  14.         Declaration  Part - This is the part of the Modula-2  source
  15.              code in which all constants,  variables, and other user
  16.              defined auxiliary operations are defined.   In some  of
  17.              the  programs we have examined,  there have been one or
  18.              more  VAR declarations and in one case a  constant  was
  19.              declared.    These  are  the  only  components  of  the
  20.              declaration  part we have used up to this time.   There
  21.              are  actually four components in the declaration  part,
  22.              and  the procedures make up the fourth part.   We  will
  23.              cover the others in the next chapter.
  24.  
  25.         Statement  Part  - This  is the last part  of  any  Modula-2
  26.              program,  and it is what we have been calling the  main
  27.              program.   It  always  exists bounded by  the  reserved
  28.              words  BEGIN  and  END  just as it has in  all  of  our
  29.              examples to this point.
  30.  
  31.              It   is  very  important  that  you  grasp  the   above
  32.         definitions because we will be referring to them  constantly
  33.         during  this chapter,  and throughout the remainder of  this
  34.         tutorial.   With that introduction, let us look at our first
  35.         Modula-2 program with a procedure in it.   It will, in fact,
  36.         have three procedures.
  37.  
  38.                             WHAT IS A PROCEDURE?
  39.  
  40.              A Procedure is a group of statements, either predefined
  41.         by  the  compiler writer,  or defined by you,  that  can  be
  42.         called  upon to do a specific job.   In this chapter we will
  43.         see  how  to  write  and  use  a  procedure.    During  your
  44.         programming in the future, you will use many procedures.  In
  45.         fact,  you have already used some because the "WriteString",
  46.         "WriteLn", etc procedures you have been using are predefined
  47.         procedures.
  48.  
  49.              Load and display the program named PROCED1.MOD for your
  50.         first look at a user defined procedure.  In this program, we
  51.         have the usual header with one variable defined.  Ignore the
  52.         header and move down to the main program beginning with line
  53.         26.  We will come back to all of the statements prior to the
  54.         main program in a few minutes.
  55.  
  56.  
  57.                                  Page 29
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.                      Chapter 5 - Modula-2 Procedures
  68.  
  69.  
  70.  
  71.              The  main  program is very easy to understand based  on
  72.         all of your past experience with Modula-2.  First we somehow
  73.         write  a header (WriteHeader),  then write a message  out  8
  74.         times  (WriteMessage),  and finally we write an  ending  out
  75.         (WriteEnding).   Notice  that  with the long names  for  the
  76.         parts,   no  comments  are  needed,   the  program  is  self
  77.         documenting.   The  only  problem we have is,  how does  the
  78.         computer  actually  do the three steps we  have  asked  for.
  79.         That  is  the purpose for the 3 procedures  defined  earlier
  80.         starting  in lines 8,  14,  and 20.   Modula-2 requires that
  81.         nothing  can  be  used until it has  been  defined,  so  the
  82.         procedures  are  required to be defined prior  to  the  main
  83.         program.   This  may  seem a bit backward to you if you  are
  84.         experienced in some other languages like FORTRAN,  BASIC, or
  85.         C, but it will make sense eventually.
  86.  
  87.                        HOW DO WE DEFINE A PROCEDURE?
  88.  
  89.              We will begin with the PROCEDURE at line 8.   First  we
  90.         must use the reserved word PROCEDURE followed by the name we
  91.         have  chosen for our procedure,  in this case  "WriteHeader"
  92.         which  is required to follow all of the rules for naming  an
  93.         identifier.   Following  the PROCEDURE line,  we can include
  94.         more IMPORT lists, define variables, or any of several other
  95.         things.   We will go into a complete definition of this part
  96.         of  the  program  in the next chapter.   I  just  wanted  to
  97.         mention  that other quantities could be inserted  here.   We
  98.         finally come to the procedure body which contains the actual
  99.         instructions  we wish to execute in the procedure.   In this
  100.         case,  the procedure body is very simple,  containing only a
  101.         "WriteString" and a "WriteLn" instruction, but it could have
  102.         been as complex as we needed to make it.
  103.  
  104.              At  the  end of the procedure,  we once again  use  the
  105.         reserved  word END followed by the same name as  we  defined
  106.         for  the procedure name.   In the case of a  procedure,  the
  107.         final  name is followed by a semicolon instead of a  period.
  108.         Other  than  this small change,  a procedure  definition  is
  109.         identical to that of the program itself.
  110.  
  111.              When  the  main  program  comes  to  the  "WriteHeader"
  112.         statement, it knows that it is not part of its standard list
  113.         of executable instructions, so it looks for the user defined
  114.         procedure  by  that name.   When it finds it,  it  transfers
  115.         control  of  the  program  sequence  to  there,  and  begins
  116.         executing those instructions.   When it executes all of  the
  117.         instructions in the procedure, it finds the END statement of
  118.         the  procedure and returns to the next statement in the main
  119.         program.   When the main program finally runs out of  things
  120.         to do, it finds the END statement and terminates.
  121.  
  122.  
  123.                                  Page 30
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.                      Chapter 5 - Modula-2 Procedures
  134.  
  135.  
  136.  
  137.              As the program executes the FOR loop, it is required to
  138.         call the "WriteMessage" procedure 8 times, each time writing
  139.         its  message  on  the monitor,  and  finally  it  finds  and
  140.         executes  the "WriteEnding" procedure.   This should be very
  141.         straightforward  and should pose no real problem for you  to
  142.         understand.   When  you think you understand what it  should
  143.         do, compile and run it to see if it does.
  144.  
  145.                   NOW FOR A PROCEDURE THAT USES SOME DATA
  146.  
  147.              The  last  program  was interesting to show you  how  a
  148.         procedure works but if you would like to see how to get some
  149.         data into the procedure,  load and display the program named
  150.         PROCED2.MOD.   We will once again go straight to the program
  151.         starting in line number 25.   We immediately notice that the
  152.         program  is nothing more than one big FOR loop which  we  go
  153.         through 3 times.  Each time through the loop we call several
  154.         procedures,  some that are system defined, and some that are
  155.         user  defined.   This  time instead of the simple  procedure
  156.         name,  we  have  a variable in the  parentheses  behind  the
  157.         variable name.   In these procedures, we will take some data
  158.         with us to the procedures,  when we call them,  just like we
  159.         have  been  doing  with  the  "WriteString"  and  "WriteInt"
  160.         procedures.
  161.  
  162.             We   will  take  some  data  to  the   procedure   named
  163.         "PrintDataOut"  where  it will be  printed.   The  procedure
  164.         "PrintDataOut"  starting  in line 9 also contains a pair  of
  165.         parentheses  with a variable named "Puppy" which is of  type
  166.         INTEGER.   This  says that it is expecting a variable to  be
  167.         passed  to  it from the calling program and it  expects  the
  168.         variable to be of type INTEGER.  Back to the main program we
  169.         see,  on line 28,  that the program did make the call to the
  170.         procedure with a variable named "Thing" which is an  INTEGER
  171.         type variable, so everything is fine.  The procedure prefers
  172.         to  call  the  variable  passed to it "Puppy"  but  that  is
  173.         perfectly  acceptable,   it  is  the  same  variable.    The
  174.         procedure writes the value of "Puppy",  which is really  the
  175.         variable  "Thing"  in the main program,  in a line  with  an
  176.         identifying string, then changes the value of "Puppy" before
  177.         returning to the main program.
  178.  
  179.              Upon  returning  to  the main  program,  we  print  out
  180.         another line with three separate parts (notice the indenting
  181.         and the way it makes the program more readable),  then calls
  182.         the  next procedure "PrintAndModify" which appears to do the
  183.         same thing as the last one.   Indeed, studying the procedure
  184.         itself  leads you to believe they are the same,  except  for
  185.         the  fact that this one prefers to use the name "Cat" for  a
  186.         variable  name.   There  is  one subtle difference  in  this
  187.  
  188.  
  189.                                  Page 31
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.                      Chapter 5 - Modula-2 Procedures
  200.  
  201.  
  202.         procedure, the reserved word VAR in the header, line 17.
  203.  
  204.                      CALL BY VALUE & CALL BY REFERENCE
  205.  
  206.              In the first procedure, the word VAR was omitted.  This
  207.         is  a  signal to the compiler that this procedure  will  not
  208.         actually  receive the variable reference,  instead  it  will
  209.         receive  a  local copy of the variable which it can  use  in
  210.         whatever way it needs to.   When it is finished, however, it
  211.         can  not  return  any changes in the variable  to  the  main
  212.         program  because  it  can  only work with its  copy  of  the
  213.         variable.  This is therefore a one-way variable, it can only
  214.         pass  data  to the procedure.   This is sometimes  called  a
  215.         "call  by value" or a "value parameter" in literature  about
  216.         Modula-2.
  217.  
  218.              In  the second procedure,  the word VAR  was  included.
  219.         This   signals  the  compiler  that  the  variable  in  this
  220.         procedure  is meant to be actually passed to the  procedure,
  221.         and not just the value of the variable.   The procedure  can
  222.         use  this variable in any way it desires,  and since it  has
  223.         access to the variable in the main program,  it can alter it
  224.         if it so desires.   This is therefore a two-way variable, it
  225.         can  pass  data from the main program to the  procedure  and
  226.         back again.   This is sometimes called a "call by reference"
  227.         or a "variable parameter" in literature about Modula-2.
  228.  
  229.                            WHICH SHOULD BE USED?
  230.  
  231.              It  is up to you to decide which of the  two  parameter
  232.         passing  schemes you should use for each  application.   The
  233.         "two-way" scheme seems to give the greatest flexibility,  so
  234.         your first thought is to simply use it everywhere.  But that
  235.         is  not  a good idea because it gives  every  procedure  the
  236.         ability  to  corrupt  your  main  program   variables.    In
  237.         addition,  if  you  use a "call by value" in  the  procedure
  238.         definition,  you have the ability to call the procedure with
  239.         a  constant  in that part of the call.   A good  example  is
  240.         given  in  lines 12,  20,  30,  34,  and 38 of  the  present
  241.         program.   If  "WriteInt"  were  defined  with  a  "call  by
  242.         reference",  we  could not use a constant here,  but instead
  243.         would  have  to set up a variable,  assign  it  the  desired
  244.         value,  then use the variable name instead of the 5.   There
  245.         are  other  considerations but they are beyond the level  of
  246.         our study at this point.
  247.  
  248.                   BACK TO THE PROGRAM ON DISPLAY, PROCED2
  249.  
  250.              We  have already mentioned that both of the  procedures
  251.         modify  their  respective local variables,  but due  to  the
  252.         difference  in "call by value" in the first,  and  "call  by
  253.  
  254.  
  255.                                  Page 32
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.                      Chapter 5 - Modula-2 Procedures
  266.  
  267.  
  268.         reference"  in the second,  only the second can actually get
  269.         the modified data back to the calling program.   This is why
  270.         they are named the way they are.   One other thing should be
  271.         mentioned.   Since  it  is not good practice to  modify  the
  272.         variable  used  to  control the  FOR  loop,  (and  downright
  273.         erroneous  in many cases) we make a copy of it and  call  it
  274.         "Thing"  for use in the calls to the procedures.   Based  on
  275.         all  we  have said above,  you should be able to figure  out
  276.         what the program will do, then compile and run it.
  277.  
  278.                      SEVERAL PARAMETERS PASSED AT ONCE
  279.  
  280.              Load  and display the program named PROCED3.MOD for  an
  281.         example  of  a  procedure  definition  with  more  than  one
  282.         variable being passed to it.   In this case four  parameters
  283.         are  passed to this procedure.  Three of the parameters  are
  284.         one-way  and  one is a two-way parameter.   In this case  we
  285.         simply  add  the  three numbers and return it  to  the  main
  286.         program.    Good  programming  practice  would  dictate  the
  287.         placement  of the single "call by reference" by  itself  and
  288.         the  others  grouped together,  but it is more important  to
  289.         demonstrate to you that they can be in any order you desire.
  290.         This  is a very straightforward example that should pose  no
  291.         problem to you. Compile and run it.
  292.  
  293.                              SCOPE OF VARIABLES
  294.  
  295.              Load and display the program PROCED4.MOD for a  program
  296.         which  can  be  used to define scope of variables  or  where
  297.         variables  can be used in a program.   The  three  variables
  298.         defined in lines 6, 7, and 8, are of course available in the
  299.         main program because they are defined prior to it.   The two
  300.         variables  defined in the procedure are available within the
  301.         procedure because that is where they are defined.   However,
  302.         because the variable "Count" is defined both places,  it  is
  303.         two  completely  separate variables.   The main program  can
  304.         never use the variable "Count" defined in the procedure, and
  305.         the procedure can never use the variable "Count" defined  in
  306.         the  main  program.   They are two completely  separate  and
  307.         unique variables with no ties between them.   This is useful
  308.         because  when your programs grow,  you can define a variable
  309.         in  a procedure,  use it in whatever way you wish,  and  not
  310.         have  to worry that you are corrupting some  other  "global"
  311.         variable.   The  variables  in the main program  are  called
  312.         "global variables" because they are available everywhere.
  313.  
  314.              In  addition  to the above scope  rules,  the  variable
  315.         named "Apple" in the procedure, is not available to the main
  316.         program.   Since  it is defined in the procedure it can only
  317.         be used in the procedure.   The procedure effectively builds
  318.         a  wall around the variable "Apple" and its own  "Count"  so
  319.  
  320.  
  321.                                  Page 33
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.                      Chapter 5 - Modula-2 Procedures
  332.  
  333.  
  334.         that neither is available outside of the procedure.  We will
  335.         see  in  the  next chapter that procedures can  be  "nested"
  336.         leading  to further hiding of variables.   This  program  is
  337.         intended to illustrate the scope of variables,  and it would
  338.         be good for you to study it, then compile and run it.
  339.  
  340.                    A PROCEDURE CAN CALL ANOTHER PROCEDURE
  341.  
  342.              Load  and display the program named PROCED5.MOD for  an
  343.         example of procedures that call other procedures.   Study of
  344.         this  program will reveal that procedure "Three" starting on
  345.         line 19 calls procedure "Two" which in turn calls  procedure
  346.         "One".  The main program calls all three, one at a time, and
  347.         the  result is a succession of calls which should be  rather
  348.         easy for you to follow.   The general rule is,  "any program
  349.         or  procedure  can  call any other procedure that  has  been
  350.         previously  defined,  and is visible to it."  (We  will  say
  351.         more  about  visibility  later.)  Study  this  program  then
  352.         compile and run it.
  353.  
  354.                             A FUNCTION PROCEDURE
  355.  
  356.              Load  and display the program named FUNCTION.MOD for an
  357.         example  of  a  "Function  Procedure".    This  contains   a
  358.         procedure  very much like the ones we have seen so far  with
  359.         one difference.   In the procedure heading, line 6, there is
  360.         an added ":  INTEGER" at the end of the argument list.  This
  361.         is a signal to the system that this procedure is a "function
  362.         procedure"  and it therefore returns a value to the  calling
  363.         program  in a way other than that provided for by  parameter
  364.         references  as we have used before.   In fact,  this program
  365.         returns a single data value that will be of type INTEGER.
  366.  
  367.              In line 16 of the calling program,  we find the call to
  368.         the  procedure  which  looks like the others  we  have  used
  369.         except that it is used in an assignment statement as  though
  370.         it is an INTEGER type variable.   This is exactly what it is
  371.         and  when the call is completed,  the "QuadOfSum(Dogs,Cats)"
  372.         will  be  replaced by the answer and then  assigned  to  the
  373.         variable  "Feet".   The  entire call can therefore  be  used
  374.         anyplace  in  a program where it is legal to use an  INTEGER
  375.         type variable.   This is therefore a single value return and
  376.         can  be very useful in the right situation.   In one of  the
  377.         earlier  program,  we  used  the "sin"  and  "cos"  function
  378.         procedures and this is exactly what they were.
  379.  
  380.              One additional point must be made here.   If a function
  381.         procedure  does not require any parameters,  the call to  it
  382.         must  include empty parentheses,  and the definition of  the
  383.         procedure  must include empty parentheses also.   This is by
  384.         definition of the Modula-2 language.
  385.  
  386.  
  387.                                  Page 34
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.                      Chapter 5 - Modula-2 Procedures
  398.  
  399.  
  400.  
  401.              In  the  procedure,  we had to do  one  thing  slightly
  402.         different  in order to get the return value and that was  to
  403.         use  the RETURN reserved word.   Whenever we have  completed
  404.         the  desired calculations or whatever we need to do,  we put
  405.         the result that is to be returned to the main program in the
  406.         parentheses  following  the RETURN and  the  procedure  will
  407.         terminate, return to the calling program, and take the value
  408.         with it as the answer.   Due to decision making, we may have
  409.         several RETURN statements in the procedure but only one will
  410.         be exercised with each call.   It is an error to come to the
  411.         END  statement  of  a function procedure  since  that  would
  412.         constitute  a  return  without  the benefit  of  the  RETURN
  413.         statement,  and  no value would be returned to  the  calling
  414.         program.
  415.  
  416.                              WHAT IS RECURSION?
  417.  
  418.              Recursion is simply a procedure calling itself.  If you
  419.         have  never  been  introduced  to  recursion  before,   that
  420.         definition sounds too simple but that is exactly what it is.
  421.         You  have  probably seen a picture containing a  picture  of
  422.         itself.   The picture in the picture also contains a picture
  423.         of  itself,  the end result being an infinity  of  pictures.
  424.         Load the file named RECURSON.MOD for an example of a program
  425.         with recursion.
  426.  
  427.              In  the  main  program,  "Count" is set to  7  and  the
  428.         procedure is called taking along "Count" as a parameter.  In
  429.         the procedure, we display a line containing the value of the
  430.         variable,  now  called  "Index",  and decrement it.  If  the
  431.         variable  is greater than zero,  we call the same  procedure
  432.         again,  this time entering it with the value of 6.  It would
  433.         be  reasonably  correct to think of the system  as  creating
  434.         another copy of the procedure for this call.   The  variable
  435.         "Index"  would  be  reduced to 5,  and another copy  of  the
  436.         procedure would be called.   Finally,  the variable would be
  437.         reduced  to  zero  and the return  path  from  procedure  to
  438.         procedure  would  be taken until the main program  would  be
  439.         reached, where the program would terminate.
  440.  
  441.              Rather than making a complete new copy of the procedure
  442.         for  each recursive call,  the same code would be  run  each
  443.         time through and all of the data would be stored away on the
  444.         "stack" each time through.   You have no need to worry about
  445.         this  because it is all taken care of for you by the system.
  446.         You  simply  call the same procedure as though it  were  any
  447.         other  procedure and the system will worry about all of  the
  448.         details except for one.   It is up to you to see that  there
  449.         is  some mechanism by which the process will terminate.   If
  450.         there were no decrementing statement in the procedure,  this
  451.  
  452.  
  453.                                  Page 35
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.                      Chapter 5 - Modula-2 Procedures
  464.  
  465.  
  466.         program  would  never  reach  an end  and  the  stack  would
  467.         overflow,  resulting in an error message and termination  of
  468.         the  program.   It  would be worth your time to  remove  the
  469.         decrementing  statement and observe this,  after you compile
  470.         and run it the way it is now.
  471.  
  472.              Recursion  can be very useful for those  problems  that
  473.         warrant  its  use.   This  example is a very stupid  use  of
  474.         recursion,  but is an excellent method for giving an example
  475.         of  a  program  with recursion that is simple  and  easy  to
  476.         understand.
  477.  
  478.                        DIRECT AND INDIRECT RECURSION
  479.  
  480.              This   example  uses  direct  recursion   because   the
  481.         procedure calls itself directly.  It is also possible to use
  482.         indirect recursion where procedure "A" calls "B",  "B" calls
  483.         "A",  etc.   Either method is available and useful depending
  484.         on the particular circumstances.
  485.  
  486.  
  487.         PROGRAMMING EXERCISES
  488.  
  489.         1.   Write a program to write your name, address, and phone
  490.              number on the monitor with each line in a different
  491.              procedure.
  492.  
  493.         2.   Add a statement to the procedure in RECURSON to display
  494.              the  value  of "Index" after the call to itself so  you
  495.              can see the value increasing as the recurring calls are
  496.              returned to the next higher level.
  497.  
  498.         3.   Rewrite TEMPCONV from chapter 4 putting the centigrade
  499.              to farenheit formula in a function procedure.
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.                                  Page 36
  520.  
  521.