[comp.lang.ada] From Modula to Oberon

fortin@zap.UUCP (Denis Fortin) (03/29/88)

In article <272@fang.ATT.COM> cbseeh@fang.ATT.COM (Edmund E Howland) writes:
>>> [talking about the definition of the Oberon language posted recently
>>>  to comp.lang.modula2]

>> In my opinion Oberon is a significant improvement over Pascal, Modula-2 
>> and Ada in one respect:  It has automatic garbage collection.  This feature
>> is enough to choose Oberon over the other three.  
> 
>Huh?
>Since when have these three ever had a need for garbage collection?
>I am not too familiar with Ada, but garbage collection exists in
>languages for whom dynamic binding is a way of life, not an option.

(note: the stuff below applies equally well to Modula-2 or Ada, although
       it is a bit more Ada-specific)

Actually, Ada *allows* but does not not *require* the existence of a
garbage collector (LRM section 4.8 paragraph 7).  While I agree that for
real-time embedded applications, a garbage collector can be annoying
(though there are incremental algorithms that make this less true), in a
language that encourages information-hiding, a good garbage collector is
almost a must (in my opinion). 

The problem is that users might be using modules/packages that contain
hidden pointers to dynamic data.  Without garbage collection, you have
to have a free/dispose/unchecked_deallocation routine available for all
hermetic data types you export, otherwise code will be written that does
not release variables of that type after using them and if at a latter
point you change the implementation of the hidden data type (which you
SHOULD be able to do, that's why you hid it's true contents in the first
place) and stick a pointer/access variable in it, then you're stuck ->
your heap will slowly erode away!

Actually, by not requiring that a user call a "free" routine for all
variables of data types you export (those where implementation is
hidden), you are allowing him/her to make a very important assumption
about the way your data type is implemented (which is bad). 

Of course, one CAN export a "free" routine with *ALL* data types, but
then it becomes a real pain to write code that uses the data type.  For
example, a "dynamic string package" would require that you call
"free(...)" for all of the string variables you declare at the end of
each block that declares such variables -> this is not only notationally
painful (!?), but also very error-prone. 

Anyway, I've been involved in a 75000+ lines Ada project, and every time
I can talk to Ada compiler vendors, I always ask them *when* garbage
collection will finally be available for their compiler.  (Put in a
pragma to turn it off for real-time applications or something...)

(Actually, the two biggest demands that my group had for Ada compilers
 (besides the obvious "fast compile" and "fast execution") where "fast
 tasking" and "garbage collection"!)

Sigh, it felt good getting this off my chest :-)
-- 
Denis Fortin                            | fortin@zap.UUCP
CAE Electronics Ltd                     | philabs!micomvax!zap!fortin
The opinions expressed above are my own | fortin%zap.uucp@uunet.uu.net

crowl@cs.rochester.edu (Lawrence Crowl) (03/30/88)

In article <429@zap.UUCP> fortin@zap.UUCP (Denis Fortin) writes:
>... in a language that encourages information-hiding, a good garbage
>collector is almost a must (in my opinion). ... Without garbage collection,
>you have to have a free/dispose/unchecked_deallocation routine available for
>all hermetic data types you export, ... [otherwise you limit subsequent
>implementations] ... but then it becomes a real pain to write code that uses
>the data type.

C++ provides the notion of a *destructor*.  Whenever you define a class
(abstract data type), you may define a destructor.  The destructor is
*implicitly* called when the variable is deleted (e.g. at the end of the
procedure for local variables).  The implementation of the class may change
from static allocation to dynamic allocation, without changing the client
code, without leaking memory, and without explicit client control of
deallocation.

Garbage collection is one approach to reducing the storage management burden
on programmers.  It is not the only approach, nor is it always the best
approach.
-- 
  Lawrence Crowl		716-275-9499	University of Rochester
		      crowl@cs.rochester.edu	Computer Science Department
...!{allegra,decvax,rutgers}!rochester!crowl	Rochester, New York,  14627

boehm@titan.rice.edu (Hans Boehm) (03/31/88)

  It seems to me that the C++ approach to storage management is at best
a partial solution.  Admittedly it succeeds at automatically deallocating
objects in trivial cases.  For some applications this is, no doubt,
sufficient.  But consider a case as simple as implementing a stack type,
whose underlying representation is a linked list.  Assume this type
includes a non-destructive "pop" operation that returns a new stack
one shorter than the old one.  The original stack is left intact.  ("Pop"
can of course be implemented as the "tail" operation on linked lists.)
Should the head of the original linked list be deallocated?  Is it reasonable
to make that the caller's responsibility?  Certainly not, since it's not
supposed to know anything about the representation of stacks.  After all,
I could be copying arrays.  The stack implementation could reference count,
but that's more tedious, error prone, and probably slower than a good
garbage collector.  It also doesn't always work.
  My experience is that any attempt at manipulation of interesting linked
structures in a language that doesn't support real automatic storage
management will either fail, or waste large amounts of debugging time.
(My experience includes a (working) 40,000 line compiler, written in C, that
manipulates a reference counted syntax "tree", or more accurately, a
reference counted syntax graph.)  Normally, it is extremely difficult
to track down bugs created by premature deallocation.  When such bugs are
finally removed, the resulting programs normally include a substantial
number of storage leaks.
  Some recent experiments by Mark Weiser and myself with retrofitting a
garbage collector to existing C programs, verify the latter point.
(The garbage collector should never free anything since that was the
programmers responsibility.  It does.  In other people's code.
Our paper on this should appear in Software P&E shortly.)
Mike Caplinger reported similar results for another application at the last
USENIX conference, I believe.  We have resurrected C code with storage
management bugs by linking it against a garbage collector (which in the case
of C doesn't always work either, but it has a better track record than manual
storage management).
  There are arguably cases in which a garbage collector is undesirable,
notably in the presence of severe real-time constraints.  But even in such
a situation, I would want a garbage collector during debugging to help
me track down storage leaks.

Hans-J. Boehm                       boehm@rice.edu
Computer Science Dept.
Rice University
Houston, TX 77251-1892