home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / object / 2976 < prev    next >
Encoding:
Internet Message Format  |  1992-07-22  |  9.3 KB

  1. Xref: sparky comp.object:2976 comp.lang.eiffel:979
  2. Newsgroups: comp.object,comp.lang.eiffel
  3. Path: sparky!uunet!psinntp!merlin.hgc.edu!jcm
  4. From: jcm@hgc.edu (James McKim)
  5. Subject: Re: How to design a data structure library.
  6. Message-ID: <1992Jul22.142916.22115@merlin.hgc.edu>
  7. Sender: usenet@merlin.hgc.edu (Action News Central)
  8. Organization: The Hartford Graduate Center
  9. References: <1820@snap> <1992Jul21.124256.17256@bony1.bony.com>
  10. Date: Wed, 22 Jul 1992 14:29:16 GMT
  11. Lines: 260
  12.  
  13. In article <1992Jul21.124256.17256@bony1.bony.com> richieb@bony1.bony.com (Richard Bielak) writes:
  14. >In article <1820@snap> paj@uk.co.gec-mrc (Paul Johnson) writes:
  15. >
  16. >[...]
  17. >
  18. >>Cursors
  19. >>-------
  20. >>
  21.  
  22. [Examples of LIST with built in cursor vs LIST with outside iterators
  23.  deleted]
  24.  
  25. >>
  26. >>The ISE system has the disadvantage that multiple iterations over a
  27. >>list are difficult to do.  In particular, an interleaved iteration
  28. >>involving two cursors at different points in the list can be very
  29. >>tricky. 
  30. >
  31. >I think that cursors should be separate from the data structure they
  32. >are used to traverse. The main reason is to allow multiple iterations
  33. >over the same list. The scheme present in the ISE library (with "mark"
  34. >and "return") works OK within a single program. It fails, when the
  35. >data structured is shared - either through a database or concurrent
  36. >process.
  37.  
  38. I agree. They also tend to add complexity to the class. And since
  39. the LIST class plays a role in a variety of other ISE library
  40. classes (e.g. TREE, WINDOW) it's complexity "contaminates" the
  41. others. It'll be interesting to see what changes ISE has made
  42. in these classes in the next release.
  43.  
  44. [...]
  45.  
  46. >>
  47. >>RISC vs CISC
  48. >>------------
  49. >>
  50. >>The ISE data structure classes have large numbers of features.  Many
  51. >>of these provide efficient short cuts.  For instance there is a list
  52. >>merge facility which removes items from one list and inserts them into
  53. >>another.  The ISE linked list implementation allows this to be done
  54. >>with a little internal pointer shuffling.  Other features are rarely
  55. >>used and do not offer efficiency short-cuts.  For instance, the
  56. >>`remove_all' procedure scans the list and removes all items which are
  57. >>equal to the argument.  This could be done just as quicly by an
  58. >>explicit loop.
  59. >>
  60. >>Inheriting from the ISE list classes can be a trial.  In order to
  61. >>provide a true subtype, one has to implement a large number of
  62. >>features, many of which are of doubtful utility and others for which
  63. >>there are no clear semantics or implementation.
  64. >>
  65. >>The SIG design has none of this.  The data structure features provide
  66. >>a bare minimum of functionality.  This makes the documentation simpler
  67. >>to use, but some tasks are less efficient than they might be.
  68. >>
  69. >
  70. >I would prefer RISC. I think it was Jim McKim, who said that the
  71. >features of a class should form a "minimum spanning" set - that is
  72. >just enough to be complete, but not more.
  73.  
  74. Yup. A minimum spanning set should be "sufficient" in the sense of
  75. Booch and, ideally, specifiable via preconditions and postconditions.
  76. There are other criteria we like to see a minimum spanning set
  77. satisfy, but these are the main ones. Paul's ideas on "fine-grained"
  78. inheritance are not unrelated here.
  79.  
  80. To be fair to ISE, the further up the inheritance hierarchy you go
  81. the more RISC-like the classes get. These classes tend to be deferred,
  82. so we users tend to use the classes at the low end of the hierarchy
  83. which are more MISC-like.
  84.  
  85. >
  86. >I've implemented a persistent list class, which did _not_ inherit from
  87. >LIST. The main reason was that LIST has too many things that I did not
  88. >want to implement for persistent lists (eg. "mark", "return",
  89. >"index_of", "duplicate).
  90.  
  91. I also often use a simpler LIST class of my own devising.
  92.  
  93. >
  94. >
  95. >>
  96. >>Functional vs Procedural
  97. >>------------------------
  98. >
  99. >[...]
  100. >>
  101. >>Things become worse when considering large objects.  The ISE SET class
  102. >>provides `intersect', `merge' and `subtract' procedures.  Hence the
  103. >>only way to create a new set `c' which is the union of two existing
  104. >>sets `a' and `b' is:
  105. >>
  106. >>    c.Clone (a);
  107. >>    c.merge (b);
  108. >>
  109. >>With some kinds of objects, this would be rather less efficient than
  110. >>
  111. >>    c := a + b;
  112. >>
  113. >>On the other hand providing operators `*' and `+' for intersection and
  114. >>union would result in something like:
  115. >>
  116. >>    a := a + b;
  117. >>
  118. >>This creates a new (and fairly large) object before throwing away the
  119. >>old value of `a'.  If this is implemented as a linked list then you
  120. >>could have a huge amount of garbage being generated.
  121. >>
  122. >>Does it make sense to implement both kinds of operations in a class,
  123. >>so that the programmer can pick the appropriate one?
  124. >>
  125. >
  126. >
  127. >I suppose one should implement only the more fundamental set of
  128. >operations, and then let the descendant create the "+" or "*"
  129. >operators if desired. This goes back to the "minimal spanning set"
  130. >idea.
  131.  
  132. Our version of the minimal spanning set for a SET class includes
  133. only       Create, Insert an element, Remove an element   as commands
  134. and        Cardinality, Has a given element               as queries.
  135.  
  136. We would leave it to descendants to provide either version of merge,
  137. intersect, and subtract. But this avoids Paul's question.
  138.  
  139. It seems to me that Union (I think ISE used 'merge' as the verb 
  140. form of union), Intersection and Difference (ditto for 'subtract' here)
  141. are fundamentally binary operations. That is, they're single valued
  142. functions of two variables, and so should be designed as such.
  143. Thus I favor the c := a + b or c := union( a, b ) form. I would
  144. add union, intersection, and difference as a first increment,
  145. through inheritance, to the minimal SET class.
  146.  
  147. Then as a second increment, I would add Merge, Intersect, and
  148. Subtract. Then document  that the typical use for Merge is
  149.  
  150.         a.merge( b ) in place of a := a + b
  151.  
  152. because the former is more efficient than the latter. Ditto
  153. for Intersect and Subtract.
  154.  
  155. >
  156. >
  157. >
  158. >>Documentation
  159. >>-------------
  160. >>
  161. >>What should go into the documentation of a cluster?
  162. >
  163. >Good question. There should be a general description of what the
  164. >classes are doing. For example, the description of data structure
  165. >cluster should talks about cursors.
  166.  
  167. Very good question. I would also want to see some examples of
  168. how the classes interact with each other, but I think we've
  169. only scratched the surface here.
  170.  
  171. >
  172. >>What should be in the documentation of each individual class?
  173. >
  174. >At least "flat class | short" :-)
  175.  
  176. And of course this does you little good unless you've done
  177. a thorough job with preconditions, postconditions, and invariants,
  178. at least as comments. Somewhere we need an example of the typical
  179. use of the class. Maybe there are three levels. Cluster level
  180. (discussed above), class level (typical use, how features interact, invariants), and feature level (preconditions and postconditions).
  181.  
  182.  
  183. >
  184. >>Do we need discussion of time and space complexity?  At what level of
  185. >>detail?
  186. >
  187. >I think so. Sometimes a simple guideline on how to use a class
  188. >efficiently would suffice.
  189.  
  190. Yup.
  191.  
  192. >
  193. >>Do we also need an outline of the implementation method?  At what
  194. >>level of detail?
  195. >
  196. >This is probably not needed, as long as the source code is available.
  197.  
  198. And as long as the information above is available. _Ideally_, if you're
  199. a client of the class, you shouldn't need the source code unless
  200. you suspect a bug. If you're inheriting from a class then more
  201. detailed documentation is certainly necessary. In particular,
  202. you're much more apt to need the source code.
  203.  
  204. >
  205. >
  206. >>Is the short-flat version of a class useful? (Sig appear to think
  207. >>not).
  208. >
  209. >It's essential.
  210.  
  211. Absolutely! If there's no easy way to obtain the public interface
  212. for a class, then much of the benefit of information hiding and
  213. encapsulation are lost. I don't know what SIG was thinking here.
  214.  
  215. Richie and I have kicked around the idea of refining short. The default
  216. version would extract the public interface of features exported to all classes
  217. (the current version). A second version would be "short for class X" which
  218. would extract the public interface of features visible to X. Since
  219. Eiffel supports selective export, this could be a proper superset 
  220. of what the default version gives. If X is a descendant
  221. of the class in question then all it's features are visible
  222. and we have the "short-for-descendants" mentioned below.
  223.  
  224. >
  225. >>Do we need a separate section: "Guide to Writing Descendants"?
  226. >
  227. >I think so. I'm in process of writing docs for a database cluster, and
  228. >large part of the doc will be on that topic.
  229. >
  230. >What would be useful is a "short-for-descendants". An extract of a
  231. >class that contains the signatures of all the features, without the
  232. >code.
  233.  
  234. This kind of documentation and more is going to be needed. Especially
  235. if vendors begin supplying libraries without source code.
  236.  
  237. >
  238. >>What sort of examples are needed?
  239. >
  240. >At least an example of typical use. Perhaps some examples that
  241. >illustrate the difference between efficient and inefficient use of the
  242. >library.
  243.  
  244. Yup, and see above.
  245.  
  246. >
  247. >
  248. >>Are inheritance graphs useful?
  249. >>
  250. >
  251. >I don't find these particularly useful, although they are pretty to
  252. >look at.
  253. >
  254.  
  255. I like 'em. I think we at least need what ISE provides in their library
  256. documentation. They show the complete inheritance hierarchy above the current
  257. class.
  258.  
  259. >
  260. >
  261. >...richie
  262. >
  263. >-- 
  264.  
  265. [...]
  266.  
  267. -- Jim
  268. -- 
  269.  
  270. *------------------------------------------------------------------------------*
  271. Jim McKim  (203)-548-2458     In exactly 3.2 seconds it will be a few 
  272. Internet:  jcm@hgc.edu   minutes to 5:00.
  273.