home *** CD-ROM | disk | FTP | other *** search
/ Solo Programadores 22 / SOLO_22.iso / docs / lovelace / lesson11.les < prev    next >
Encoding:
Text File  |  1995-11-21  |  8.3 KB  |  246 lines

  1. <COMMENT This is a lesson file for the Lovelace Ada tutorial>
  2. <COMMENT A program called genlesson is used to transform this file into a set>
  3. <COMMENT of useful HTML files for use by Mosaic & other WWW browsers.>
  4.  
  5. <COMMENT  Edit the following lines. >
  6. <TUTOR NAME="Lovelace">
  7. <LESSON NUMBER=11>
  8. <AUTHOR NAME="David A. Wheeler" EMAIL="wheeler@ida.org">
  9. <AUTHOR ADDRESS="<A HREF="dwheeler.htm">David A. Wheeler (wheeler@ida.org)</A>">
  10. <COMMENT $Id: lesson11.les,v 1.4 1995/08/09 21:07:40 wheeler Exp $ >
  11.  
  12. <COMMENT  You'll probably want to uncomment and edit these lines: >
  13. <COMMENT  <PREVIOUS_LESSON LOCATION="URL_of_directory/" >
  14. <COMMENT  <NEXT_LESSON LOCATION="URL_of_directory/" >
  15.  
  16. <COMMENT A lesson is divided into 1 or more "sections".>
  17. <COMMENT Each section has a title; SECTION starts a new section.>
  18.  
  19. <SECTION NAME="Defining Generics">
  20. It's often useful to first create a more generic version of a subprogram
  21. or package and then use that generic version to create more specific
  22. subprograms or packages.
  23. Ada's capability to do this is called a <EM>generic</EM>, and it's
  24. the same thing as C++'s <EM>templates</EM>.
  25. Generics are also somewhat similar to C's "#define" preprocessor command,
  26. though Ada generics are type-checked and thus much safer.
  27. <P>
  28. It's probably easiest to understand this by example.
  29. First, let's write a procedure to swap two Integers:
  30. <P>
  31. <PRE>
  32.   procedure Swap(Left, Right : in out Integer) is
  33.     Temporary : Integer;
  34.   begin
  35.     Temporary := Left;
  36.     Left := Right;
  37.     Right := Temporary;
  38.   end Swap;
  39. </PRE>
  40. <P>
  41. Swap is a perfectly fine procedure, but it's too specialized.
  42. We can't use Swap to swap Floats, or Unbounded_Strings, or anything else.
  43. What we want is a more generic version of Swap, but one where we can
  44. substitute the type "Integer" with a more <EM>generic</EM> type.
  45. A generic version of Swap would look like this:
  46. <P>
  47. <PRE>
  48.   generic
  49.     type Element_Type is private;
  50.   procedure Generic_Swap(Left, Right : in out Element_Type) is
  51.     Temporary : Element_Type;
  52.   begin
  53.     Temporary := Left;
  54.     Left := Right;
  55.     Right := Temporary;
  56.   end Generic_Swap;
  57. </PRE>
  58. <P>
  59. In general, to create a generic version of a subprogram (or package),
  60. write the subprogram using a few generically-named types.
  61. Then precede the subprogram or package with the keyword ``generic''
  62. and a list of the information you'd like to make generic.
  63. This list is called the <EM>generic formal parameters</EM>; this list is
  64. like the list of parameters in a procedure declaration.
  65. We'll explain more later
  66. what the phrase ``is private'' means.
  67. <P>
  68. To use a generic subprogram (or package), we have to create a real
  69. subprogram (or package) from the generic version.
  70. This process is called <EM>instantiating</EM>, and the result is
  71. called an <EM>instantiation</EM> or <EM>instance</EM>.
  72. These are big words for a simple concept.
  73. For example, here's how to create three Swap procedure instances
  74. from the generic one:
  75. <P>
  76. <PRE>
  77.   procedure Swap is new Generic_Swap(Integer);
  78.   procedure Swap is new Generic_Swap(Float);
  79.   procedure Swap is new Generic_Swap(Unbounded_String);
  80. </PRE>
  81. <P>
  82. Note that when you instantiate a generic, you ``pass'' types
  83. in the same way that you pass parameters to an ordinary procedure call.
  84. <P>
  85. From here on, you can call the Swap procedure that takes Integers, the
  86. Swap procedure that takes Floats, and the Swap procedure that takes
  87. Unbounded_Strings.
  88. Thus if A and B are both of type Integer, Swap(A,B) would swap their values.
  89.  
  90. <SECTION NAME="Generic Formal Parameters">
  91. We will only look a little bit at generics, just enough so you'll
  92. understand what they can do.
  93. However, it's difficult to read and use generics if you don't understand
  94. what can be used in a generic formal parameter
  95. (i.e. the stuff right after the keyword "generic").
  96. Here are the things that can be
  97. included in a generic formal parameter list:
  98. <UL>
  99. <LI>Values or variables of any type. These are called `formal objects'.
  100. For example, a maximum size might be a useful formal object.
  101. <LI>Any type. These are called `formal types'.
  102. <LI>Packages which are instances of other generic packages.
  103. These are called `formal packages'; we won't discuss them further here.
  104. </UL>
  105. <P>
  106. Here's an example of a formal_object_declaration:
  107. <P>
  108. <PRE>
  109.    Maximum_Size : Integer;
  110. </PRE>
  111. <P>
  112. Here's the syntax for defining a value or variable as a formal object
  113. in <A HREF="bnf.htm">BNF</A> format:
  114. <P>
  115. <PRE>
  116.   formal_object_declaration ::= identifier_list ":" [ "in" | "in out" ]
  117.                                 type_name [ ":=" default_expression ] ";"
  118. </PRE>
  119. <P>
  120. We've already seen an example of a formal type declaration.
  121. Formal types specify the name of a type and what ``kind of type'' is permitted.
  122. A formal
  123. type declaration specifies the "minimum" or "worst case" kind of
  124. type that is required.
  125. The most minimal type in Ada is called a "limited private" type.
  126. This is the "worst case" because the keyword "private"
  127. means that you may not know anything about how it's implemented,
  128. and "limited" means that there might not be
  129. assignment or equality operations defined for it.
  130. <P>
  131. A formal type declaration has the following syntax (this is actually
  132. highly simplified; many more things are permitted):
  133. <P>
  134. <PRE>
  135.   formal_type_declaration ::= "type" defining_identifier "is"
  136.                               formal_type_definition ";"
  137.  
  138.   formal_type_definition ::= ["tagged"] ["limited"] "private" | "(<>)"
  139. </PRE>
  140. <P>
  141. Let's look at some examples, with their meaning written beside them:
  142. <P>
  143. <PRE>
  144.   type Item is limited private;  -- Item can be any type.
  145.   type Item is private;          -- Item can be any type that has assignment
  146.                                  -- (:=) and equal-to (=) operation.
  147.   type Item is tagged limited private; -- Item can be any tagged type.
  148.   type Item is tagged private;   -- Item can be any tagged type with :=.
  149.   type Item is (<>);             -- Item can be any discrete type, including
  150.                                  -- Integer and Boolean.
  151. </PRE>
  152. <P>
  153. In the next section we'll look at an example that should make these
  154. things clearer.
  155.  
  156. <QUESTION Type=Multiple-Choice>
  157. If you want to create a generic with a formal type named Unit
  158. that could be any type at all, how would you declare it?
  159. <CHOICES>
  160. <CHOICE ANS=1>type Unit is limited private;
  161. <CHOICE ANS=2>type Unit is private;
  162. <CHOICE ANS=3>type Unit is (<>);
  163. </CHOICES>
  164. <ANSWER ANS=1>
  165.  
  166. <SECTION NAME="Example of a Generic Package">
  167. Let's look an example of a generic package.
  168. This example of a generic package is straight from the
  169. <A HREF="http://lglwww.epfl.ch/Ada/LRM/9X/rm9x/rm9x-12-08.html">Ada
  170. LRM section 12.8</A>.
  171. <P>
  172. Let's imagine that you want to create a generic package for a Stack
  173. that takes operations Push and Pop.
  174. Here's one way to define such a Stack; we'll define a Stack package that
  175. stores some Item type and has a maximum size:
  176. <P>
  177. <PRE>
  178.   generic
  179.     Size : Positive;
  180.     type Item is private;
  181.   package Stack is
  182.     procedure Push(E : in  Item);
  183.     procedure Pop (E : out Item);
  184.     Overflow, Underflow : exception;
  185.   end Stack;
  186. </PRE>
  187. <P>
  188. Now a definition needs to be implemented, so here's a sample implementation:
  189. <P>
  190. <PRE>
  191.   package body Stack is
  192.     type Table is array (Positive range <>) of Item;
  193.     Space : Table(1 .. Size);
  194.     Index : Natural := 0;
  195.  
  196.     procedure Push(E : in Item) is
  197.     begin
  198.       if Index >= Size then
  199.         raise Overflow;
  200.       end if;
  201.       Index := Index + 1;
  202.       Space(Index) := E;
  203.     end Push;
  204.  
  205.     procedure Pop(E : out Item) is
  206.     begin
  207.       if Index = 0 then
  208.         raise Underflow;
  209.       end if;
  210.       E := Space(Index);
  211.       Index := Index - 1;
  212.     end Pop;
  213.  
  214.   end Stack;
  215. </PRE>
  216. <P>
  217. Somewhere else you can instantiate this generic Stack package.
  218. If you wanted to instantiate a new package called ``Stack_Int''
  219. which could hold 200 Integers, you could say:
  220. <P>
  221. <PRE>
  222.   package Stack_Int is new Stack(Size => 200, Item => Integer);
  223. </PRE>
  224. <P>
  225. The ``Size =>'' and ``Item =>'' are optional; you could omit them
  226. if you wanted to.
  227. From then on, you could "Push" a new Integer onto Stack_Int by saying:
  228. <P>
  229. <PRE>
  230.   Stack_Int.Push(7);
  231. </PRE>
  232. <P>
  233.  
  234. <QUESTION Type=Multiple-Choice>
  235. What are the formal parameters for generic package Stack?
  236. <CHOICES>
  237. <CHOICE ANS=1>Size, Positive, Item, and private.
  238. <CHOICE ANS=2>Size and Item.
  239. <CHOICE ANS=3>Size.
  240. </CHOICES>
  241. <ANSWER ANS=2>
  242. <RESPONSES>
  243. <WHEN ANS=1>
  244. Well, all that text is in there, but there are only two parameters.
  245. </RESPONSES>
  246.