home *** CD-ROM | disk | FTP | other *** search
/ Solo Programadores 22 / SOLO_22.iso / docs / lovelace / lesson6.les < prev    next >
Encoding:
Text File  |  1995-11-21  |  16.6 KB  |  468 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. <TUTOR NAME="Lovelace">
  6. <LESSON NUMBER=6>
  7. <AUTHOR NAME="David A. Wheeler" EMAIL="wheeler@ida.org">
  8. <AUTHOR ADDRESS="<A HREF="dwheeler.htm">David A. Wheeler (wheeler@ida.org)</A>">
  9.  
  10. <COMMENT $Id: lesson6.les,v 1.8 1995/09/22 21:38:21 wheeler Exp wheeler $ >
  11.  
  12. <COMMENT A lesson is divided into 1 or more "sections".>
  13. <COMMENT Each section has a title; SECTION starts a new section.>
  14.  
  15. <SECTION NAME="Type Float">
  16. For the next few sections we'll learn a little more about
  17. Ada types. We've already seen Ada's built-in type Integer.
  18. <P>
  19. Like Integer, Ada also has a predefined type called <EM>Float</EM>.
  20. Float can store fractional values and `large' values.
  21. <EM>Float</EM> is used when you don't care about the
  22. minimum or maximum range of numbers, nor about the minimum
  23. accuracy of the value - the Ada compiler
  24. will choose whatever is most `natural' for the machine.
  25. Type `Float' is not appropriate if you
  26. <EM>do</EM> care about the range or accuracy;
  27. Ada has ways to specify these.
  28. <P>
  29. Float has all the arithmetic
  30. (+, -, *, /, **, etc.) and comparison (=, /=, >, >=, <, <=)
  31. operations you'd expect.
  32. The ``**'' operator means ``exponentiate'', a common
  33. operation very useful for programs doing significant computation.
  34. <P>
  35. Ada insists that types be correct in operations, and there
  36. aren't any predefined operations for mixing Integer and Float using
  37. +, -, *, or /. Thus, if you're using an Integer and Float together,
  38. put a function called `Float()' around the Integer variables to
  39. cause them to be converted into floating-point values.
  40. This makes it clear when such conversions are taking place, which is
  41. sometimes important in understanding what a program is doing.
  42. Also, whenever you set a Float to a constant, the constant must
  43. be written with a period in it, or the compiler will complain.
  44. <P>
  45. Here are some examples:
  46. <PRE>
  47.  with Float_Text_IO;
  48.  use Float_Text_IO;
  49.  procedure Think is
  50.    A, B : Float := 0.0; -- A and B initially zero; note the period.
  51.    I, J : Integer := 1;
  52.  begin
  53.    A := B + 7.;
  54.    I := J * 3;
  55.    B := Float(I) + A;
  56.    Put(B);
  57.  end Think;
  58. </PRE>
  59. <P>
  60. It's important that you understand the general limitations of floating
  61. point numbers on digital computers.
  62. Floating point numbers are usually stored as a
  63. binary approximation using a limited number of bits.
  64. The upshot is that results are usually only
  65. approximately the value you'd expect.
  66. Even numbers that are represented exactly in decimal may only
  67. be approximate when converted to an internal floating point number.
  68. Thus, be wary of using "=" to compare
  69. two floating point numbers.
  70. This isn't specific to Ada - Fortran, C, Pascal, and so on
  71. all do the same thing.
  72. For more information on this subject, see
  73. <A HREF="biblio.htm#goldberg1991">David Goldberg's 1991
  74. survey on floating-point arithmetic</A>.
  75.  
  76. <QUESTION Type=Multiple-Choice>
  77. In procedure Think defined above, what will be printed out as
  78. the final value of B?
  79. <CHOICES>
  80. <CHOICE ANS=1>10.0
  81. <CHOICE ANS=2>0.0
  82. <CHOICE ANS=3>7.0
  83. </CHOICES>
  84. <ANSWER ANS=1>
  85. <RESPONSES>
  86. <WHEN ANS=1>
  87. Right!
  88. <WHEN ANS=2>
  89. Sorry.
  90. <WHEN ANS=3>
  91. Sorry.
  92. </RESPONSES>
  93. <SECTION NAME="Boolean">
  94. Ada also predefines a simple type called <EM>Boolean</EM>,
  95. which can only have two values, <EM>True</EM> and <EM>False</EM>.
  96. All of the comparison operations (=, >=, /=, etc.) have result
  97. values of type Boolean.
  98. All conditions (such as what goes after an <EM>if</EM> and <EM>while</EM>)
  99. must be of type Boolean.
  100. <P>
  101. There are a few special infix operations that take two Booleans and
  102. result in a Boolean: and, or, and xor (exclusive-or),
  103. with their usual meanings.
  104. The value of `True and False' is False, while the value of `True or False'
  105. is True.
  106. `Exclusive or' is true if either of two conditions, but not both, is true.
  107. <P>
  108. There is also the prefix operation ``not''.
  109. If a boolean variable A has the value True, `not A' has the value False.
  110. <P>
  111. Although you can probably guess what the values of any combination
  112. of values is, here they are officially:
  113. <PRE>
  114. --- When ---+------------------- Then -----------------
  115. A     B     | (A and B)   (A or B)   (A xor B)  (not A)
  116. True  True  |   True        True       False     False
  117. True  False |   False       True       True      False
  118. False True  |   False       True       True      True
  119. False False |   False       False      False     True
  120. </PRE>
  121. <P>
  122. Normally Ada will evaluate these
  123. expressions in whatever order is most efficient for the machine.
  124. If it's important to evaluate them in a certain order
  125. and to stop evaluating them when the answer is known, there are
  126. versions of `and' and `or' that are called `short-circuit operations'.
  127. These operations
  128. will execute strictly left-to-right and will not execute anything
  129. if they don't have to.
  130. C's && and || operations work this way.
  131. The short-circuit version of `and' is `and then'; the short-circuit
  132. version of `or' is `or else'. For example, if
  133. you want to do something if K isn't zero and
  134. 1.0/K is more than B, but you realize that the latter test <EM>must</EM>
  135. be done after the former:
  136. <P>
  137. <PRE>
  138.  if K /= 0 and then 1.0/Float(K) > B then ...
  139. </PRE>
  140.  
  141. <QUESTION Type=Multiple-Choice>
  142. Which of the following is True?
  143. <CHOICES>
  144. <CHOICE ANS=1>(True and False)
  145. <CHOICE ANS=2>not (True or False)
  146. <CHOICE ANS=3>True and then True
  147. </CHOICES>
  148. <ANSWER ANS=3>
  149.  
  150. <SECTION NAME="Creating Types and Subtypes">
  151. In Ada, a <EM>type</EM> is characterized by a set of values
  152. and a set of <EM>primitive operations</EM>.
  153. For example, the type Integer can be characterized by a set of
  154. values (..., -2, -1, 0, 1, 2, ...) and a set of primitive
  155. operations (+, -, *, /, etc.).
  156. We'll learn more about the phrase ``primitive operation'' later.
  157. <P>
  158. An <EM>object</EM> of a given type is a run-time entity that
  159. contains (has) a value of the type.
  160. For example, a variable named `Number_Of_Widgets' is an object;
  161. Number_Of_Widgets could be of the type <EM>Integer</EM>.
  162. <P>
  163. Ada lets you create your own types, and has a very rich set
  164. of capabilities for creating types with exactly the operations
  165. you want.
  166. <P>
  167. To create a new type, use a <EM>type declaration</EM>.
  168. A type declaration begins with the keyword <EM>type</EM>, followed
  169. by the name of the new type, the keyword <EM>is</EM>, and then
  170. a definition of the new type.
  171. Here's an example of a new type named <EM>Column</EM> which can
  172. only have integer values in the range 1 through 72, and another
  173. type called <EM>Row</EM> that has values 1 through 24:
  174. <P>
  175. <PRE>
  176.  type Column is range 1 .. 72;
  177.  type Row    is range 1 .. 24;
  178. </PRE>
  179. <P>
  180. One <EM>very</EM> important difference between Ada and some other
  181. languages is that Ada considers types different even if
  182. they happen to be implemented the same way at a particular time.
  183. For example, an object of type Column can't be added with an object
  184. of type Row or Integer without some additional expressions, even though they
  185. may be implemented the same way in the (current) underlying system.
  186. Why? Because they have different types.
  187. Now, you could <EM>create</EM> such operations to allow them to be mixed,
  188. but these operations don't come automatically.
  189. <P>
  190. This prohibition of mixing types is often useful for catching errors,
  191. but sometimes it's not what you want.
  192. Beginning Ada programmers sometimes create too many different numeric types,
  193. turning simple programs into complicated ones.
  194. If two different types are closely related and it should be possible
  195. to mix the different types together,
  196. perhaps you have two related types instead of two independent types.
  197. What you probably need in that case is a <EM>subtype</EM> declaration.
  198. <P>
  199. A <EM>subtype</EM> is simply another name for an existing type
  200. that may have some additional constraints on it.
  201. For example, let's say you have a program that manipulates counts
  202. of many different kinds of things.
  203. You could have a base type called `Count', and subtypes to represent
  204. counts of different kinds of things.
  205. If there must be less than 100,000 things, and widgets must have less
  206. than 100 (while there's no specific limit for eggs), you could define
  207. these subtypes as follows:
  208. <PRE>
  209.  type Count is range 0 .. 99_999;
  210.  subtype Widget_Count is Count range 0 .. 99;
  211.  subtype Egg_Count is Count;
  212. </PRE>
  213. <P>
  214. Don't get the idea that new types are always a bad thing, however;
  215. there are a number of places where creating a new type for numeric
  216. values is very appropriate.
  217. Ada provides you with a number of tools; you need to decide which
  218. tool is appropriate for your task.
  219.  
  220. <QUESTION Type=Multiple-Choice>
  221. If you want to permit free mixing of two different kinds of numbers,
  222. should they be defined as subtypes or different types?
  223. <CHOICES>
  224. <CHOICE ANS=1>subtypes
  225. <CHOICE ANS=2>types
  226. </CHOICES>
  227. <ANSWER ANS=1>
  228.  
  229. <SECTION NAME="Enumeration">
  230. Often a variable can have only one of a small set of values.
  231. An <EM>enumeration</EM> type can be created for such variables,
  232. making it easier to understand and permitting error detection.
  233. For example, let's say that a variable
  234. `Today' must be one of seven values, Monday through Sunday.
  235. Let's call the list of legal values type `Day', and set
  236. `Today' to Tuesday as an example:
  237. <P>
  238. <PRE>
  239.  type Day is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);
  240.  subtype Weekday is Day range Monday .. Friday;
  241.  subtype Weekend is Day range Saturday .. Sunday;
  242.  -- ... some time later
  243.  Today : Day;
  244.  -- ... Here's an example of setting Today to a value.
  245.  Today := Tuesday;
  246. </PRE>
  247. <P>
  248. Here's a simplified <A HREF="bnf.htm">BNF</A> for
  249. declaring enumeration types:
  250. <P>
  251. <PRE>
  252.  enumeration_type_declaration ::=
  253.    "("  enumeration_literal_specification
  254.       {  "," enumeration_literal_specification }  ")"
  255. </PRE>
  256. <COMMENT No question >
  257.  
  258. <SECTION NAME="Arrays">
  259. An array type in Ada can contain many components with the same subtype.
  260. An Ada array is quite similar to arrays in many other languages,
  261. but here are some important things to know about them:
  262. <P>
  263. <OL>
  264. <LI>
  265. Ada array indices are not required to start at zero or one.
  266. Array indices can begin (and end) with any discrete value - whatever
  267. makes the most sense for the data.
  268. This means that you can start arrays at -5 (if that makes sense),
  269. and you can use enumerated values as indices as well.
  270. Ada programs usually use a starting index of 1 if there's
  271. no particularly natural starting point; this reduces the
  272. probability of so-called ``one-off'' errors
  273. (people normally count from one, not zero, and
  274. can sometimes get confused when starting from zero).
  275. <LI>
  276. Like many other things in Ada, array accesses (both read and write)
  277. are normally checked at run-time.
  278. Thus, if the array index is out-of-bounds,
  279. instead of quietly doing the wrong thing (as C and C++ do),
  280. an <EM>exception</EM> will be raised.
  281. This catches a surprisingly large number of errors.
  282. <LI>
  283. Multi-dimensional arrays are handled in an intuitive way.
  284. <LI>
  285. A directive can be used to <EM>pack</EM> arrays, which requests
  286. the compiler to store the array in a memory-efficient way.
  287. This is particularly handy for arrays of Boolean and Character values.
  288. <LI>
  289. Using a value from an array intentionally looks like a function call.
  290. That way, if you change an array into a function, code that uses
  291. the values often needs relatively few changes.
  292. <LI>
  293. You can define array types without completely fixing their
  294. minimum and maximum size.
  295. These are called `unconstrained' arrays.
  296. While they are very useful, we will discuss them further later.
  297. </OL>
  298. <COMMENT ??? Haven't discussed Character type >
  299. <P>
  300. Here are a few examples:
  301. <P>
  302. <PRE>
  303.  -- Sample array type definitions:
  304.   type Table is array(1 .. 100) of Integer; -- 100 Integers.
  305.   type Schedule is array(Day) of Boolean; -- Seven Booleans.
  306.   type Grid is array(-100 .. 100, -100 .. 100) of Float; -- 40401 Floats.
  307.  -- Sample variable declarations:
  308.   Products_On_Hand : Table;   -- This variable has 100 Integers.
  309.   Work_Schedule : Schedule;
  310.   Temperature : Grid;
  311.  -- And sample uses:
  312.   Products_On_Hand(1) := 20;  -- We have 20 of Product number 1
  313.   Work_Schedule(Sunday) := False; -- We don't work on Sunday.
  314.   Temperature(0,0) := 0.0;  -- Set temperature to 0.0 at grid point (0,0).
  315.   Put(Products_On_Hand(1)); -- Print out the number 20.
  316. </PRE>
  317.  
  318. <COMMENT No question. We haven't shown the BNF. >
  319.  
  320. <SECTION NAME="Records">
  321. Types can be a complex collection of other types;
  322. the primary method for collecting these is through the <EM>record</EM>
  323. (which is basically identical to the Pascal record and C struct).
  324. For example, here's an example of a record useful for recording dates:
  325. <P>
  326. <PRE>
  327.  type Date is
  328.   record
  329.    Day   : Integer range 1 .. 31;
  330.    Month : Integer range 1 .. 12;
  331.    Year  : Integer range 1 .. 4000 := 1995;
  332.   end record;
  333. </PRE>
  334. <COMMENT ??? Haven't discussed this kind of range stuff >
  335. <P>
  336. The record component `Year' has an example of an `initialization clause' -
  337. any object created with this type automatically has initial values
  338. given in initialization clauses.
  339. <P>
  340. Creating variables of a record type is done the same way as any other
  341. type.
  342. A record component is referenced by using the variable name, a period,
  343. and the name of the record component.
  344. For example, let's create a variable called Ada_Birthday, and set
  345. its values to December 10, 1815:
  346. <P>
  347. <PRE>
  348.  procedure Demo_Date is
  349.    Ada_Birthday : Date;
  350.  begin
  351.    Ada_Birthday.Month := 12;
  352.    Ada_Birthday.Day   := 10;
  353.    Ada_Birthday.Year  := 1815;
  354.  end Demo_Date;
  355. </PRE>
  356.  
  357. <QUESTION Type=Multiple-Choice>
  358. If you had the following record type:
  359. <P>
  360. <PRE>
  361.  type Complex is
  362.   record
  363.     Real_Part, Imaginary_Part : Float := 0.0;
  364.   end record;
  365. </PRE>
  366. <P>
  367. and you declared the following type:
  368. <P>
  369. <PRE>
  370.   X : Complex;
  371. </PRE>
  372. <P>
  373. How would you set X's Real_Part to 1?
  374.  
  375. <CHOICES>
  376. <CHOICE ANS=1>Complex.X.Real_Part := 1.0;
  377. <CHOICE ANS=2>X.Real_Part := 1.0;
  378. <CHOICE ANS=3>Real_Part.X := 1.0;
  379. </CHOICES>
  380. <ANSWER ANS=2>
  381.  
  382. <SECTION NAME="Private and Limited Types">
  383. When creating a new type you often want to restrict
  384. the operations that users can perform on them.
  385. Two methods are particularly important: declaring
  386. types as <EM>private</EM>, and declaring them as <EM>limited</EM>.
  387. <P>
  388. When declaring a type in a package declaration, you
  389. can declare the type as <EM>private</EM>, and then complete
  390. the definition in a section of the package declaration in a section
  391. called the <EM>private</EM> part.
  392. If a type is declared as <EM>private</EM>, other packages can only
  393. use the operations that you provide and the default
  394. assignment (:=) and equality (=) operations.
  395. <P>
  396. Here's an example.
  397. Let's say that you want to create a type called `Key', which
  398. uniquely identifies some resource; you only want people to be
  399. able to Request a key and determine if one key was requested
  400. before another (let's call that operation "<").
  401. Here's one way to implement this
  402. (this example is inspired by the
  403. <A HREF="http://lglwww.epfl.ch/Ada/LRM/9X/rm9x/rm9x-07-03-01.html">Ada
  404. LRM section 7.3.1</A>):
  405. <P>
  406. <PRE>
  407.  package Key_Manager is
  408.    type Key is private;
  409.    Null_Key : constant Key;         -- a deferred constant.
  410.    procedure Get_Key(K : out Key);  -- Get a new Key value.
  411.    function "<"(X, Y : Key) return Boolean; -- True if X requested before Y
  412.  private
  413.    Max_Key  : constant := 2 ** 16 - 1;
  414.    type Key is range 0 .. Max_Key;
  415.    Null_Key : constant Key := 0;
  416.  end Key_Manager;
  417. </PRE>
  418.  
  419. Note that the type declaration in the package declaration is
  420. declared as `private'.
  421. This is later followed by the word `private' introducing the
  422. `private part' of the package specification.
  423. Here the type can be defined, as well as any constants necessary
  424. to complete its definition.
  425. Although Key is actually a numeric type, other
  426. packages cannot use addition, multiplication, and other numeric
  427. operations because Key is declared as `private' - the only operations
  428. are those defined in the package (and := and =).
  429. <P>
  430. What if we don't want the default assignment (:=) and equals-to (=)
  431. operations?
  432. The answer: we declare the type as <EM>limited</EM>.
  433. A limited type doesn't have the default assignment and equals-to
  434. operations defined.
  435. Usually the term <EM>limited</EM> is combined with private,
  436. and such a type is called a <EM>limited private</EM> type.
  437. Here's how Key would be defined using the limited keyword:
  438. <P>
  439. <PRE>
  440.   type Key is limited private;
  441. </PRE>
  442.  
  443. <QUESTION Type=Multiple-Choice>
  444. How would you define a type if you wanted <EM>only</EM>
  445. operations called `up' and `down' associated with it?
  446. <CHOICES>
  447. <CHOICE ANS=1>private
  448. <CHOICE ANS=2>limited private
  449. <CHOICE ANS=3>non-private
  450. </CHOICES>
  451. <ANSWER ANS=2>
  452. <RESPONSES>
  453. <WHEN ANS=1>
  454. No, sorry.
  455. That would also have assignment and equals-to operations.
  456. <WHEN ANS=2>
  457. Right. Here's what that might look like:
  458. <P>
  459. <PRE>
  460. package Up_And_Down is
  461.   type Up_And_Down_Type is limited private;
  462.   procedure Up(U : Up_And_Down_Type);
  463.   procedure Down(U : Up_And_Down_Type);
  464. end Up_And_Down;
  465. </PRE>
  466. <WHEN ANS=3>
  467. </RESPONSES>
  468.