home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / m / mod2tutr.zip / CHAP13.TXT < prev    next >
Text File  |  1989-01-18  |  29KB  |  647 lines

  1.  
  2.                                                     Chapter 13
  3.  
  4.                                      MODULES, LOCAL AND GLOBAL
  5.  
  6.  
  7.  
  8. PREREQUISITES FOR THIS MATERIAL
  9. ______________________________________________________________
  10.  
  11. Before attempting to understand this material, you should have
  12. a good grasp of the principles taught in Part I of this
  13. tutorial.  None of the material from Part II is required to
  14. do a meaningful study of modules in Modula-2.
  15.  
  16.  
  17. WHAT GOOD ARE MODULES?
  18. ______________________________________________________________
  19.  
  20. Modules are the most important feature of Modula-2 over its
  21. predecessor Pascal, making it very important for you to
  22. understand what they are and how they work.  Fortunately for
  23. you, there are not too many things to learn about them and
  24. after you master them, you will find many uses for them as you
  25. develop programs, and especially large programs.  Keep in
  26. mind, as you study this material, that modules are meant to
  27. organize a program to make it understandable to the original
  28. programmer, and to the person assigned to do the maintenance
  29. on the program.
  30.  
  31. Examine the program named LOCMOD1.MOD for      ===============
  32. your first example of a program with an          LOCMOD1.MOD
  33. embedded module.  Modules are nothing new      ===============
  34. to you because every program you have
  35. examined has been a module.  At this time, however, we will
  36. introduce a local module.
  37.  
  38.  
  39. WHAT IS A LOCAL MODULE?
  40. ______________________________________________________________
  41.  
  42. A local module is simply a module nested within another
  43. module, just like the present example.  The module named
  44. LocalStuff in lines 8 through 21 is nested within the main
  45. module and is heavily indented for clarity.  Since nothing is
  46. imported into the local module, nothing that belongs to the
  47. main module can be seen from within the nested module.  In
  48. addition, since the procedure GetNumber is the only thing
  49. exported from the local module, nothing else is available to
  50. the main module.  In effect, the local module is an
  51. impenetrable wall through which nothing can pass without the
  52. benefit of the import and export list.  In this case, the
  53. variable Counter cannot be read or modified by the main
  54. module, either intentionally or accidentally and the procedure
  55. GetNumber will very stubbornly refuse to allow any flexibility
  56. in its output, adding three to its internally stored variable
  57. each time it is called.  It may seem to you that this result
  58.  
  59.                                                           13-1
  60.  
  61.                         Chapter 13 - Modules, Local and Global
  62.  
  63. can be accomplished easily by using another procedure without
  64. the module but we will see shortly that it will not be the
  65. same.
  66.  
  67. Throughout the following discussion of modules, keep in mind
  68. that a module is an impenetrable wall through which nothing
  69. can pass without use of an import or export list.
  70.  
  71.  
  72. THE BODY OF THE LOCAL MODULE
  73. ______________________________________________________________
  74.  
  75. The body of the local module has one statement contained
  76. within it in line 20, "Counter := 4;", which is executed only
  77. when the module is loaded, and at no other time.  This is
  78. therefore an initialization section for the module.  Any valid
  79. executable statements can be put here and they will be
  80. executed when the program is loaded, or you can omit the body
  81. altogether by omitting the begin and any executable
  82. statements.  Actually, this body is no different than the body
  83. of the main program since it too is executed one time when the
  84. program is loaded, except for the fact that the main program
  85. is required to have a body or you will have no program.  The
  86. body can have a return statement included in it.  If the
  87. return statement is executed, the remainder of the body will
  88. not be executed, but will be ignored.
  89.  
  90.  
  91. THE MODULE VERSUS THE PROCEDURE
  92. ______________________________________________________________
  93.  
  94. We must digress a bit to see the difference in these two
  95. important topics in Modula-2.  A procedure is an executable
  96. section of code whereas a module is a grouping of variables,
  97. constants, types, and procedures.  A module is not executed
  98. since it is simply a grouping identifier, except of course for
  99. the main module which is defined as the main program.
  100. The variables in a procedure do not exist when it is not being
  101. executed, but instead are generated dynamically when the
  102. procedure is called.  A variable therefore, has a lifetime
  103. associated with it in addition to a type and a scope of
  104. visibility.  This may seem strange to you, but if you think
  105. about it for awhile, it will help explain how recursive
  106. procedure calls work.  The module, on the other hand, exists
  107. anytime it's surrounding code exists, in this case, the main
  108. program.  Since the module always exists, the variable Counter
  109. also always exists because it is defined as a part of the
  110. module.  If this variable were defined within a procedure, it
  111. would be automatically regenerated every time the procedure
  112. were called it and would therefore not remember the value it
  113. contained the prior time the procedure was called.  We could
  114. choose to define the variable as global and it would therefore
  115. always be available and never regenerated, but we would be
  116. left with the possibility of anything in the program modifying
  117.  
  118.                                                           13-2
  119.  
  120.                         Chapter 13 - Modules, Local and Global
  121.  
  122. it either accidentally or on purpose.  The ability to isolate
  123. a variable and other objects from the rest of the program is
  124. called information hiding, and has become a highly visible
  125. topic in software engineering in recent years.  In a program
  126. as small as this one, accidental corruption of data is not a
  127. problem, but it is intended to illustrate the solution to a
  128. problem embedded in a much larger program.
  129.  
  130. Suppose, for example, that you wished to generate random
  131. numbers for some use within a program.  You could include all
  132. of the code within a module using the module body for the seed
  133. initialization, and a procedure to generate one random number
  134. each time it was called.  The structure would be essentially
  135. the same as that given here, but the actual code would be
  136. different.  Nothing in the main program or any of its
  137. procedures could in any way corrupt the job given to the
  138. random number generator.
  139.  
  140.  
  141. BACK TO THE EXAMPLE PROGRAM
  142. ______________________________________________________________
  143.  
  144. In this case we have one local module defined within the main
  145. module but as many as desired could be used, and we have one
  146. procedure in the local module whereas we could have as many
  147. as desired.  In fact, we could have local modules embedded in
  148. a procedure, or in other local modules.  There is no real
  149. limit as to how you can structure your program to achieve the
  150. desired results.  One thing must be remembered.  If you embed
  151. a local module within a procedure, all of it's variables are
  152. defined dynamically each time the procedure in which it is
  153. embedded is called, and the local module's body is also
  154. executed each time the procedure is called.  This can be used
  155. to advantage in some situations, but it would be best to leave
  156. this construct to the future when you have more experience
  157. with Modula-2.
  158.  
  159. In the body of the main module you will find nothing new
  160. except for the call to the function procedure GetNumber()
  161. which is really nothing new to you.  Since GetNumber() is
  162. exported from the local module, it is available for use in the
  163. main program.  Compile and run the program to see if it does
  164. what you expect it to do.
  165.  
  166.  
  167. TWO LOCAL MODULES
  168. ______________________________________________________________
  169.  
  170. It would be well to point out at this time that if you define
  171. two local modules at the same level, one could export a
  172. variable, procedure, constant, or type and the other could
  173. import it and use it in any legal fashion.  If a record or
  174. enumeration type is exported, all of the associated
  175. identifiers are exported also, and are available anyplace the
  176.  
  177.                                                           13-3
  178.  
  179.                         Chapter 13 - Modules, Local and Global
  180.  
  181. type is imported.  You therefore have the ability to very
  182. carefully define the mechanism by which the two modules
  183. interact.
  184.  
  185. It is even possible to export procedures of the same name from
  186. more than one module, but at least one is required to use a
  187. qualified export to prevent a name clash.  More will be said
  188. about this later.
  189.  
  190. Of course, as you probably realize by now, anything exported
  191. from either of the two local modules are available for use by
  192. the main program without importing them.
  193.  
  194.  
  195. ANOTHER LOCAL MODULE
  196. ______________________________________________________________
  197.  
  198. The program we have been inspecting had        ===============
  199. the procedure exported without                   LOCMOD2.MOD
  200. qualification, so it could only be             ===============
  201. referred to by its simple name.  This
  202. could have led to a naming conflict which can be solved by
  203. using a qualified export as is done in the next program.
  204. Examine the program named LOCMOD2.MOD.  This program is very
  205. similar to the last one except for moving the output
  206. statements to the procedure.
  207. First, you should notice that the procedure name is exported
  208. using EXPORT QUALIFIED which allows the use of the qualified
  209. call to the procedure in line number 25.  There can never be
  210. a conflict of names in calling a procedure this way because
  211. it is illegal to use the same name for a module more than once
  212. at any level.  In a local module, you have a choice of using
  213. either qualified or unqualified export of items, but the
  214. exported items must all be of the same export type because
  215. only one export list is allowed per module.
  216.  
  217.  
  218. IMPORTING INTO A LOCAL MODULE
  219. ______________________________________________________________
  220.  
  221. The three output procedures are used in the local module
  222. MyStuff, but because it is only permissible to import items
  223. from a module's immediate surroundings, the procedures must
  224. first be imported into the main module.  Remember that a
  225. module is actually an impenetrable wall which nothing can get
  226. through without benefit of being imported or exported.  The
  227. display output procedures are imported into the main module
  228. in line 4, but they are not automatically imported into
  229. MyStuff.  Line 9 is required to import them into the local
  230. module.  They had to be imported through two barriers in this
  231. case.
  232.  
  233. The procedure named WriteStuff is even more tightly controlled
  234. than that in the last program because this one doesn't even
  235.  
  236.                                                           13-4
  237.  
  238.                         Chapter 13 - Modules, Local and Global
  239.  
  240. return a value to the calling program.  It updates its own
  241. internally stored value, displays it, and returns control to
  242. the calling program.
  243.  
  244. Compile and execute this program, and when you are sure you
  245. understand the new concepts covered here, we will go on to
  246. global modules.
  247.  
  248.  
  249. GLOBAL MODULES
  250. ______________________________________________________________
  251.  
  252. As useful as local modules are, they must take a back seat to
  253. the global module with which you are already fairly familiar
  254. because you have been using them throughout this tutorial.
  255. The modules InOut, Terminal, and FileSystem are examples of
  256. global modules that you already know how to use.  Now you will
  257. learn how to write your own global modules that can be
  258. imported and used in any program in exactly the same way as
  259. these standard modules.
  260. A global module is not executable, it is simply a collection
  261. of related types, variables, and procedures.  It is meant to
  262. group items in a meaningful way.
  263.  
  264.  
  265. YOUR FIRST DEFINITION MODULE
  266. ______________________________________________________________
  267.  
  268. In order to get started, examine the           ===============
  269. program named CIRCLES.DEF at this time.          CIRCLES.DEF
  270. The first thing you will notice is that we     ===============
  271. used a different extension for this file
  272. because there is another part to the program with the same
  273. name and the usual extension MOD.  This is the definition part
  274. of the global module and it serves two very important
  275. purposes.  First, it defines the interface you need to use the
  276. module in one of your programs, and secondly, it defines the
  277. details of the interface for the compiler so it can do type
  278. checking for you when you call this module.  The Modula-2
  279. compiler uses the information contained here to check all
  280. types and numbers of variables during separate compilation,
  281. just like it would do in a program compiled as a complete
  282. unit.
  283.  
  284. This program actually does very little.  In fact, its purpose
  285. is to do nothing because there are no executable statements
  286. in it.  It is only to define the interface to the actual
  287. program statements contained elsewhere.  Notice that the
  288. procedures are exported using the qualified option.  All
  289. identifiers that are exported from a definition module must
  290. be qualified so that the user has the option of importing them
  291. either way.  It is legal to export procedures, variables,
  292. constants, or types for use elsewhere as needed for the
  293. programming problem at hand, but the majority of exported
  294.  
  295.                                                           13-5
  296.  
  297.                         Chapter 13 - Modules, Local and Global
  298.  
  299. items will probably be procedures.  It should be obvious that
  300. nothing within the module is available to any other part of
  301. the program unless it is exported.
  302.  
  303. The export list is not actually required because according to
  304. the Modula-2 definition, all identifiers in a definition
  305. module are automatically exported.  Most experienced
  306. programmers include the export list for explicit
  307. documentation.
  308.  
  309.  
  310. WHAT ABOUT QUALIFIED EXPORT?
  311. ______________________________________________________________
  312.  
  313. If the identifiers are exported using the qualified export,
  314. the user has a choice of importing using the qualified method
  315. or the unqualified method.  If the entire module is imported
  316. using the qualified form;
  317.  
  318.      IMPORT Stuff;
  319.  
  320. then the various entities must be referred to using the
  321. qualident form such as Stuff.ProcedureName.  If the module is
  322. imported using the unqualified form;
  323.  
  324.      FROM Stuff IMPORT ProcedureName, ...;
  325.  
  326. then the various entities have the qualifier removed, and the
  327. simple procedure names can be used to refer to the procedures
  328. and variables.
  329.  
  330. Once again, we need to discuss a new construct in Modula-2.
  331. The newest and preferred method of importing a module using
  332. the qualified form is given as;
  333.  
  334.      FROM Stuff IMPORT;
  335.  
  336. This is identical to the qualified form given above because
  337. it imports all entities and the programmer is required to use
  338. the qualident form in the program, but it greatly simplifies
  339. the compiler writers job.  It will eventually be required, but
  340. at this point in time, few compilers will require it so the
  341. alternate form will be used in this edition of the Modula-2
  342. tutorial.
  343.  
  344.  
  345. THE IMPLEMENTATION MODULE
  346. ______________________________________________________________
  347.  
  348. We are not finished with the definition        ===============
  349. part of the module yet but we will look at       CIRCLES.MOD
  350. the implementation part of it for a few        ===============
  351. moments.  Examine the program named
  352. CIRCLES.MOD at this time.  This is the part of the module that
  353.  
  354.                                                           13-6
  355.  
  356.                         Chapter 13 - Modules, Local and Global
  357.  
  358. actually does the work.  Notice that there are three
  359. procedures here, two of which were defined in the definition
  360. part of the module making them available to other programs.
  361. The procedure named GetPi, in lines 4 through 7, is a hidden
  362. or private procedure that is only available for use within
  363. this module.  The other two procedures are available to any
  364. program that wishes to use them provided it imports them
  365. first, just as we have been doing with other procedures in
  366. this tutorial.  They are therefore referred to as visible
  367. procedures.
  368.  
  369.  
  370. Anything defined in the definition part of the module is also
  371. available here for use without redefining it, except for the
  372. procedure headers, which must be completely defined in both
  373. places.
  374.  
  375. Note that export is not allowed from an implementation module
  376. since the definition module defines the external interface and
  377. anything in the implementation module is hidden.
  378.  
  379.  
  380.  
  381. MORE ABOUT THE USE OF TWO PARTS
  382. ______________________________________________________________
  383.  
  384. The definition part of the module defines the public
  385. information about the module and the implementation part of
  386. the module defines the private or hidden information about the
  387. module.  It may seem sort of silly to go to the trouble of
  388. separating a module into two parts but there are at least
  389. three good reasons for performing this separation.
  390.  
  391. 1.   You may not care how the module is implemented.  In all
  392.      of the programs we have run up to this point, you
  393.      probably didn't care how the WriteString procedure did
  394.      its job.  You only wanted it to do the job it was
  395.      supposed to do to aid you in learning to use Modula-2
  396.      efficiently.  It would have been senseless to have
  397.      cluttered your monitor with the details of how it worked
  398.      every time you wanted to know how to use it.
  399.  
  400. 2.   It hides details of implementation.  If you were working
  401.      on a large programming project and you were assigned the
  402.      job of writing a procedure for others to use that did
  403.      some well defined task, you would define the interface
  404.      carefully and be finished.  If, however, one of the users
  405.      studied your detailed code and found a way to trick it
  406.      into doing something special, he may use the trick in his
  407.      part of the program.  If you then wanted to improve your
  408.      routine and remove the code that allowed the trick, the
  409.      interface would no longer work.  To prevent this, you
  410.      give others only the interface to work with and they
  411.      cannot look for tricks.  As mentioned earlier, this is
  412.  
  413.                                                           13-7
  414.  
  415.                         Chapter 13 - Modules, Local and Global
  416.  
  417.      called information hiding and is a very important
  418.      technique which is used on large projects.
  419.  
  420. 3.   It allows for orderly development.  It is possible to
  421.      define all of the definition parts of the modules and
  422.      have all members of the development team agree to the
  423.      interface.  Long before the details of the individual
  424.      procedures are worked out, the entire team knows what
  425.      each procedure will do and they can all begin detailed
  426.      work on their respective parts of the overall system.
  427.      This is very effective when used on a large team effort.
  428.  
  429.  
  430. COMPILATION ORDER IS IMPORTANT
  431. ______________________________________________________________
  432.  
  433. In order for the above principles to work effectively, a very
  434. definite order of compilation must be adhered to.  If the
  435. identifiers declared in the definition part are automatically
  436. available in the implementation part of the module, then it
  437. is obvious that the definition part must be compiled before
  438. the implementation part of the module can be compiled.  Also,
  439. if the definition part is modified and recompiled, then the
  440. implementation part may also require modifications to comply
  441. with the changes and it must also be recompiled.
  442.  
  443. The next rule is not nearly so obvious but you will understand
  444. it when we explain it.  When a calling module is compiled, it
  445. checks each of the imported identifiers to see that the types
  446. and number of variables agree with the calling sequences used
  447. in the program.  This is part of the strong type checking done
  448. for you by Modula-2.  If you modify and recompile one of the
  449. called definition modules and attempt to link the program
  450. together, you may have introduced a type incompatibility.  In
  451. order to prevent this, Modula-2 requires you to recompile
  452. every module that calls a modified definition module.  It does
  453. this by generating a key when you compile a definition module
  454. and storing the key when you compile the calling module.  If
  455. you attempt to link a program with differing keys, this
  456. indicates that the definition module was changed, resulting
  457. in a new key and hence a mismatch, and the linker will
  458. generate an error.
  459.  
  460.  
  461. WHY ALL OF THIS TROUBLE?
  462. ______________________________________________________________
  463.  
  464. It may not seem to be worth all of the extra trouble that the
  465. Modula-2 compiler and linker go through to do this checking,
  466. but it is important for a large program.  The information used
  467. in the definition part of the module is the type of
  468. information that should be well defined in the design stages
  469. of a programming project, and if well done, very few or no
  470. changes should be required during the coding phase of the
  471.  
  472.                                                           13-8
  473.  
  474.                         Chapter 13 - Modules, Local and Global
  475.  
  476. project.  Therefore it is expected that recompiling several
  477. definition modules should not happen very often.  On the other
  478. hand, during the coding and debugging phase of the project,
  479. it is expected that many changes will be required in the
  480. implementation parts of the modules.  Modula-2 allows this and
  481. still maintains very strong type checking across module
  482. boundaries to aid in detecting sometimes very subtle coding
  483. errors.
  484.  
  485. The above paragraph should be interpreted as a warning to you.
  486. If you find that you are constantly recompiling modules due
  487. to changes in the definition modules, you should have spent
  488. more time in the software design.
  489.  
  490.  
  491.  
  492. NOW TO ACTUALLY USE IT ALL
  493. ______________________________________________________________
  494.  
  495. With all of that in mind, it will be necessary for you to
  496. reload the program named CIRCLES.DEF which is the definition
  497. part of the module, and compile it.  Your compiler will
  498. generate several different files for use in cross checking.
  499. After you get a good compile, reload the program named
  500. CIRCLES.MOD which is the implementation part of the module and
  501. compile it.  During this compile, some of the files generated
  502. by CIRCLES.DEF will be referred to.  It would be an
  503. interesting exercise to modify a procedure call in one of the
  504. programs to see what kind of an error is displayed.  After a
  505. good compile on both of these modules, you have a new module
  506. in your library that can be used just like any of the other
  507. global libraries that came with your compiler.  This module
  508. cannot be executed because it does not contain a main program,
  509. it is only a collection of useful procedures.
  510.  
  511. Examine the program GARDEN.MOD for an         ================
  512. example of a program that calls and uses         GARDEN.MOD
  513. your new library or global module.  This      ================
  514. program is very simple and should pose no
  515. problem in understanding for you.  The two new procedures are
  516. imported and used just like any other procedure.  Be sure to
  517. compile and run this program.
  518.  
  519. Examine the program named GARDEN2.MOD for      ===============
  520. an example of the use of unqualified             GARDEN2.MOD
  521. import.  In this case, we input all            ===============
  522. exported procedures and must use the
  523. qualifier for each call as illustrated in lines 12 and 13.
  524. The program executes identically to the last program, but be
  525. sure you compile and execute it to verify that it really is
  526. identical.
  527.  
  528.  
  529.  
  530.                                                           13-9
  531.  
  532.                         Chapter 13 - Modules, Local and Global
  533.  
  534. A FINAL WORD ABOUT GLOBAL MODULES
  535. ______________________________________________________________
  536.  
  537. From the above description of global modules, it may not be
  538. very obvious to you that it is perfectly legal for one global
  539. module to call another which in turn calls another, etc.
  540. Program structure is entirely up to you.  For example, we
  541. could have called WriteString and some of our other familiar
  542. procedures from within the AreaOfCircle procedure.  The order
  543. of compilation must be kept in mind , however, or you will not
  544. get a good compilation and linking of your completed program.
  545.  
  546. Remember that there is nothing magic about the global or
  547. library (the names are synonymous) modules supplied with your
  548. compiler.  They are simply global modules that have already
  549. been programmed and debugged for you by the compiler writer.
  550. This is probably a good time to mention to you that you may
  551. have only received the source code for the definition part of
  552. the library modules with your compiler.  Many compiler writers
  553. will supply the source code for the implementation part of the
  554. library modules only if you supply them with a little more
  555. money.  After all, they are in business for the money and most
  556. people never wish to modify the supplied routines but are
  557. happy to use them as is.  Compiler writers must supply you
  558. with the definition part of the library modules because they
  559. are your only means of interfacing with them.
  560.  
  561.  
  562. THE OPAQUE TYPE
  563. ______________________________________________________________
  564.  
  565. The opaque type is illustrated in the         ================
  566. example program named OPAQUETY.DEF.             OPAQUETY.DEF
  567. Examination of line 6 will reveal that the    ================
  568. actual type is not defined, only its name.
  569. In this case the structure of the type will be hidden from the
  570. user of this module in order to effect a measure of
  571. information hiding, which we mentioned earlier.  You will
  572. notice that the opaque type (so called because it is hidden
  573. from view) is used in each of the procedure headers.  The type
  574. is used once in each header, but it could be used more times
  575. if needed, or not used at all if the problem dictated it.
  576. The next example program named                ================
  577. OPAQUETY.MOD gives the implementation of        OPAQUETY.MOD
  578. the complete module and as you can see,       ================
  579. the type is completely defined here as a
  580. pointer to a record.  Since the definition is in the
  581. implementation module, it is effectively hidden from view to
  582. the outside world.  You should have no problem understanding
  583. the details of the implementation.
  584.  
  585. The example program named OPTYPE.MOD makes use of the opaque
  586. type exported from the OpaqueType module.  There are a few
  587. rules which must be followed here.  Since the structure of the
  588.  
  589.                                                          13-10
  590.  
  591.                         Chapter 13 - Modules, Local and Global
  592.  
  593. opaque type is not exported, the user         ================
  594. cannot work with individual elements, but        OPTYPE.MOD
  595. can only use the procedures made available    ================
  596. to him by the writer of the module.  The
  597. only operations which the user is allowed to do on variables
  598. of the opaque type are assignment as illustrated in lines 12
  599. through 14, and comparison for equality or inequality as
  600. illustrated in line 29.
  601.  
  602. Only the simple types and pointers are allowed to be used as
  603. opaque types, according to the original definition of Modula-
  604. 2.  The newest additions to the language allow the use of
  605. records and arrays also, but since most compilers do not have
  606. this feature added yet, they are not illustrated here.  The
  607. preceeding three files could be easily changed to export an
  608. opaque type of a record if your compiler supports it.
  609.  
  610.  
  611. THE PROCEDURE TYPE, SOMETHING NEW
  612. ______________________________________________________________
  613.  
  614. Examine the program named PROCTYPE.MOD for    ================
  615. an example of a procedure type.  In line        PROCTYPE.MOD
  616. 6, we define a variable named OutputStuff     ================
  617. to be a procedure type of variable that
  618. requires an ARRAY OF CHAR as an argument.  This variable name
  619. can now be used to refer to and call any procedure that uses
  620. a single ARRAY OF CHAR as an argument.
  621.  
  622. In the definition part of the program two procedures are
  623. defined, each of which uses a single ARRAY OF CHAR as an
  624. argument.  In the main program, the variable OutputStuff is
  625. successively assigned each of the new procedures and used to
  626. call them.  In addition, it is used to call the supplied
  627. procedure WriteString to illustrate the possibility of doing
  628. so.  Finally, the procedures are all called in their normal
  629. manner to illustrate that there is nothing magic about them.
  630. Any procedure type can be used to call any procedures that use
  631. the same number and types of parameters as those defined when
  632. it is created as a variable.
  633.  
  634. This is a relatively new operation since it is not available
  635. in the other popular programming languages.  It is also a
  636. construct that you will not use very much, if ever, so nothing
  637. more will be said about it in this tutorial.
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.                                                          13-11
  646.  
  647.