home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / lang / ada / 2601 < prev    next >
Encoding:
Text File  |  1992-09-14  |  6.2 KB  |  117 lines

  1. Newsgroups: comp.lang.ada
  2. Path: sparky!uunet!stanford.edu!eos!aio!dnsurber
  3. From: dnsurber@lescsse.jsc.nasa.gov (Douglas N. Surber)
  4. Subject: Re: Controlling Type Definition - Is it useful/necessary?
  5. Message-ID: <dnsurber.716479211@node_26400>
  6. Sender: news@aio.jsc.nasa.gov (USENET News System)
  7. Organization: Lockheed Engineering and Sciences
  8. References: <1992Sep10.162550.5675@saifr00.cfsat.honeywell.com>
  9. Distribution: comp.ada
  10. Date: 14 Sep 92 14:00:11 GMT
  11. Lines: 104
  12.  
  13.  
  14. In order to discuss how to properly control type definitions, you must
  15. consider what purpose types serve. Obviously they are used to define
  16. storage. All that is required to accomplish that is to say "this thing
  17. takes up this many bits". Second, they allow you to specify certain
  18. types of built in functionality, such as indexing or floating point
  19. multiply. This is pretty well covered by integers, floats, chars,
  20. pointers, arrays and records. Not much sophistication required. Finally
  21. they are used to tell the compiler and the maintainer something about
  22. the program. Does the value of one object relate (more or less) directly
  23. to the value of another object _with_ _in_ _the_ _logical_ _space_ _of_
  24. _this_ _program_.  If so they should have the same type, if not, not.
  25. This is where the full power of Ada's type system is needed.
  26.  
  27. Like everything else, type definitions can be described to exist along a
  28. continuum between two extremes--those types specified by the interface
  29. to a package and those and those that exist solely to describe/support
  30. the specific implementation of the computation the package performs.
  31. The types of objects that directly relate to the interface, such as the
  32. types of parameters, storage of intermediate results, etc should be
  33. tightly controlled, as you described. Clearly the value of these objects
  34. are closely related.  But in a package of any complexity there may be
  35. other objects which, while influencing the result, are not as closely
  36. related to the result.  The types of these object should be chosen to
  37. convey as much information about the computation as possible.
  38. Arbitrarily restricting the programmer's ability to define new types of
  39. this kind will reduce the quality of the code. It takes away one of
  40. Ada's biggest strengths.
  41.  
  42. In the first paragraph I said that types are used to tell the compiler
  43. about the program. I feel I ought to clarify that statement. Testing of
  44. programs is *HARD*. Compilation is easy.  The compiler can verify
  45. certain correctness properties of a program using the information in the
  46. types.  Each correctness property of a program that is expressed in the
  47. types is one that you don't have to worry about in testing. (Sure you
  48. want to test for it anyway, but that's just reasonable paranoia.)  If I
  49. define a new type "Foo_Array_Index" and use it as the index type for an
  50. array, then I _know_ that I haven't mistakenly used "Bar_Array_Index" to
  51. access "Foo_Array".  This eliminates a whole class of errors.  This can
  52. be taken to extreemes--you can define a new type for everything. Of
  53. course this doesn't tell the compiler anything since every time two
  54. objects are "combined" you have to do type casting.  Ultimately this is
  55. a judgement call.  The extreemes are obvious, but stuff gets muddy in
  56. the middle.
  57.  
  58. Guidelines for creating new types are certainly in order. But in my
  59. opinion there are no simple syntatic rules. This is one of those skills
  60. that distinguishes good programmers from poor ones--the ability to write a
  61. program that is not only correct and efficient but readable, testable,
  62. and robust in the face of changes.  Good use of the type system improves
  63. those properties.
  64.  
  65. I am presently working with a group to improve the speed of a rather
  66. large package. The profiler tells us that 10-12% of the cycles are spent
  67. TRUPping (Trim Right, UPper case) strings. The interface has a number of
  68. parameters of type "String", and the internals of the package require
  69. that those string parameters be TRUPped. The implementation TRUPs just
  70. about every use of every string, so of course most of those strings have
  71. already been TRUPped multiple times.  Obviously the thing to do is to
  72. just TRUP things once and then forget about it.  But this is a large
  73. package with several people working on it and unknown future generation
  74. having to maintain it.  Our solution is to derive a new type,
  75. "Trupped_String", from an existing type "Pascal_String", and write a
  76. procedure, "Trup_String (arg : in String) return Trupped_String", that
  77. trims and upper cases its argument.  Then we convert args at the
  78. interface and don't worry much after that.  Because this is a new type,
  79. the compiler can find certain kinds of errors for us, and for future
  80. maintainers.  Additionally, maintainers will be constantly reminded that
  81. these strings need to be TRUPped.
  82.  
  83. As far as specific guidelines go, I can think of the following:
  84.  
  85.     Use the interface types unless there are good reasons not to.
  86.     There often are good reasons not to, but be sure you have thought
  87.     about them before creating a new type.
  88.  
  89.     Don't create a new type from thin air if you can reasonablly derive
  90.     it from an existing type.  This will help with precision problems.
  91.  
  92.     If you are type casting two types back and forth all over the place,
  93.     consider making them the same type.  However, if there is a clear
  94.     conceptual transformation that occurs with the type casting, consider
  95.     writing a function that captures that transformation and using it
  96.     instead of the bare type coersion.
  97.  
  98.     If two objects are never "combined" (transitively) then they should
  99.     be of different types.  If they aren't the same then don't say they
  100.     are the same by making them the same type.
  101.  
  102. This last is especially important when it comes to array indices.  I
  103. think every array should have its own distinct index type so there is no
  104. problem with getting indices mixed up.
  105.  
  106. This has all been about creating new types. Subtypes are less of a
  107. problem. I use them every where I can to specify range constraints.
  108. This is a help with testing, but since you can mix and match subtypes to
  109. your hearts desire, they don't give you much help at compile time.
  110.  
  111. This has gone on rather longer than I intended, I hope it helps. 
  112. Sorry I had to post it, but I don't have email access. :(
  113.  
  114. Douglas Surber
  115. Lockheed
  116. Houston, TX
  117.