HABERNOL@DB0TUI11.arpa.UUCP (02/05/87)
> Second, concerns the initialization problems with Modula-2 ADTs. > When a procedure is called with an uninitialized ADT, a test for > undefined is impossible, and a simple test for nil is obviously > insufficient. One solution is [...] > [...] > Declaring ADT's as pointers to headers, and keeping a list of > pointers to these headers would help, but I'm hoping someone will post > a better solution (if anyone sees problems with this approach, please > let me know too). > > Also, does anyone know of a method to provide automatic cleanup upon > termination of an ADT's environment? > > Bob Hathaway > afd@k.cc.purdue.edu It is impossible to implement a "safe" ADT in Modula-2. It would require some modifications of the language. You would need full control over the objects of this type. The exporting module must be informed on allocation and deallocation of this object (i.e. at scope entry and scope exit). Furthermore you must have control over all operations on these objects. You may write an init, fin, assign routine, but this is very unsafe (because it requires that the user applies *only* your operations in the *correct* order. I haven't seen such a user :-) Such calls had to be generated automatically by the compiler (block entry, block exit, explicit assignation (":="), implicit assignation (parameter passing)). You may protect your implementation of the ADT (by keeping a list of pointers to objects of this type, or by magic numbers). This will result in additional overhead, but it doesn't garuantee integrity of data. Problem with list of pointers mentioned above: Because you can't catch the assignations you have no chance to decide how many valid references to an object exists. Another problem comes from the missing signals on scope exit. No chance for your internal bookkeeping. It wouldn't be very hard to modify Modula to allow safe implementations of abstract data types (some procedures must be bound to the type declaration, calls are generated by the compiler for allocation/deallocation/assignment). I have implemented such a system for an extended Pascal dialect several years ago. After you have done these modifications you would have a nice language but you will have to find a new name for it because it wouldn't be Modula-2 any longer. Thomas Habernoll - HABERNOL@DB0TUI11.BITNET - ...!mcvax!unido!tub!thh
nagler@seismo.CSS.GOV@olsen.UUCP (02/06/87)
It is impossible to implement a "safe" ADT in Modula-2. I have been using ADTs extensively for quite a while. I have read lots of articles on them and I will take the liberty of inferring that "safe" means the programmer won't be chasing bugs. My experience with the word "safe" is kind of funny. For example, I was reading about the automatic garbage collection (AGC) system in Cedar. It seems really spiffy except the system doesn't know how to AGC circular data structures (e.g. doubly linked lists). It is up to the programmer to "do the right thing", that is, implement his own "clean up" code to properly deallocate the structure. Modula-2 isn't safe and neither is Cedar. They are close, but not perfect. Like I said, we use ADTs. We use both the linked list and magic number stuff for protection. It seems to work. In fact, I haven't chased a NIL pointer bug in a very long time. We currently only use the linked list stuff for deallocation control. So it is just the magic numbers (and NIL) that seems to be saving us. Every since we put in the linked list (or a simpler equivalent), out of memory bugs were real easy to chase. We do non-stop (hopefully) real time systems. When we do terminate, the system dumps a status of the memory allocation by module. Our modules aren't huge or tightly coupled, so it easy to trace the culprit. Where's the beef? Well, it is the same old thing. Modula-2 is fast, simple and almost elegant. It runs on a lot of computers which really can't have AGC. It runs on all kinds of operating systems. Cedar doesn't exactly fit in all these categories. I am not thrilled with Modula-2. It needs a fair amount of work, but it is livable with a few simple rules. The rules we try to follow are: 0 Programmers are stupid; reviews increase their IQ. 1 Always have "Create" and "Destroy" code for objects. 2 Use termination procedures to clean up your act. 3 When in doubt, get out of there. 4 Don't trust anybody unless you know them. 5 Clean up after yourself. There are more, of course, but these are the ones that pertain to the discussion. Rule 0 is my byword and I am lucky that I have had good reviewers. Rule 1 is easy to enforce with rule 0. Rule 2 is picked up by the last guy out (our ADT manager, if we put it in debugging mode). Rule 3 is just a good idea, that is, if you find something is wrong and you don't know how to fix it (e.g. telling the user to re-enter the number), you can't continue. Rule 4 says, check your inputs if they aren't already type checked. This means that you should check out opaque types which are passed into exported procedures. The last rule is interesting. It is the first rule of our lives: "Clean up your room!" Of course, no one ever follows it, which is why God invented mothers (sorry, Mom). Moms are pretty good at cleaning up except when you make messes to quickly or the ratio of garbage generators to Moms is high. I make messes to quickly. AGC's are glorified mothers. They work ok until you starting making too many messes, too quickly. If the AGC continually follows you around, it can clean up just fine. However, you need another processor to do the work of one when things get busy. The AGC can be lazy, but then it has a hard time figuring out where you left all of your trash which can be annoying in real time environments. My mother is a smart woman, as most mothers are, and she used to say: "If you just put it away in the first place, you wouldn't have to go back later to clean it up!" This is my byword for software. You open a file, read from it, and then you close it. 1,2,3. A,B,C. If you set up the rythm(sp?), anyone can learn to do it. I haven't seen an AGC that could "safely" manage a serial port or IP/TCP connection. Maybe I deal with this stuff a lot, so I think it is important to handle real situations like cleaning up the screen upon program exit. But wait, what about the beginning programmer!?! Beginning programmers, I have found, do not use ADTs. They don't understand data abstractions like trees, how are they going to invent their own? We have a lot of students working with us. They don't chase out of memory bugs or trashed pointers. They seem to fit right into our environment with a bit of tutoring. To build large systems, you need good habits. If you grow up with someone cleaning up after yourself all the time, you end up being a messy person. Why not just start the game out right? ADTs are absolutely necessary to do programming these days. It isn't clear that AGC and operator overloading decreases programming time, but it may decrease hacking time. I wonder if the Modula-2+ guys at DEC/SRC can provide project development times to compare with vanilla Modula-2 environments. It would be an interesting study. Rob Nagler