Path: utzoo!attcan!uunet!mcsun!ukc!cam-cl!scc
From: scc@cl.cam.ac.uk (Stephen Crawley)
Newsgroups: comp.sw.components
Subject: Re:  Re: Garbage Collection & ADTs
Message-ID: <909@scaup.cl.cam.ac.uk>
Date: 23 Sep 89 02:46:59 GMT
References: <900@scaup.cl.cam.ac.uk> <6530@hubcap.clemson.edu>
Sender: news@cl.cam.ac.uk
Organization: U of Cambridge Comp Lab, UK
Lines: 124

Bill Wolfe wrote:
>>> This ADT will do dynamic allocation INTERNALLY so as to facilitate
>>> its own expansion and contraction as necessary.  Upon block exit, 
>>> the ADT's destroy procedure will be invoked, and all the space
>>> occupied by the ADT will be released.

I replied:
>> OK ... in the trivial case your scheme does work.  The conditions
>> for it to work include:
>> 
>> a)	NO references to the ADT are passed out of scope.

Bill replied:
>   In keeping with the general principle that application programmers
>   should not be using pointers; appropriate ADTs should be used instead.
 
An I claim that it is IMPOSSIBLE to build sufficiently general library 
ADT's!  See article <902@scaup.cl.cam.ac.uk> for an example.  [And I've 
a better one up my slieve ;-)]

I wrote:
>> b)	the scope exits before you run short of space.

Bill replies:
>  Or you have programmed your application to properly handle the
>  exception STORAGE_ERROR.  The sequence is then as follows:
>
> [Bill then describes a scheme where the application catches a 
> STORAGE_ERROR exception, causes the current transaction to be 
> aborted and throws away some (global) data structures after 
> asking the user.]

This is unrealistic.  It assumes that there are enough large global 
data structures to be thrown.  It also assumes that the application
contains the necessary code for interacting with the end user; i.e. 
asking questions that he/she has a chance of understanding.  Neither
will be true in general.

I wrote:
>> c)	the programmer (i.e. the application!) does not incorrectly tell 
>> 	the ADT to release an instance too soon.

Bill replies:
> Since the default is that the ADT will die automatically upon going
> out of scope, the user will presumably refrain from invoking Destroy
                    ^^^^
        [he means programmer I think ...]
		    
> without a fairly good reason.

In this case the *good reason* is that the scope does not exit soon 
enough; if the programmer doesn't reclaim the ADT before scope exit, 
the program will run out of space and die.

I wrote:
>> GC'ed memory management can reclaim junk (heap nodes that are no longer
>> needed) whenever it runs out of space, whereas a scope based scheme
>> can in general only identify and hence reclaim junk on scope exit.
>> In other words, scope based reclamation of memory will in general 
>      need more memory.

Bill replied:
> Not true.  Consider -- what precisely is junk?  

I define junk to mean dynamically allocated space which was allocated
in the current scope (or passed down from a higher scope) that is no
longer accessible from an in-scope variable anywhere in the program.

In a complex program, such junk may be generated in such a way that 
it IMPOSSIBLE for any application code or any library ADT to keep track 
of its accessibility ... without implementing a garbage collector!

Bill continues:
> If we define it as "memory that is no longer needed due to 
> deallocate operations" [...]

No thats not what I meant ...

Bill continues:
> If we define junk as "memory which is strictly not necessary at this 
> point in the program" 

This is approximately what I mean ...

> then we require a "Read Programmer's Mind" instruction.

Oh no we don't!!!!  A garbage collector can (and will) reclaim a lot of 
this junk by tracing all in-scope variables etc.  The garbage collector
can do a "perfect" job of this.  Storage reclamation code in an ADT or 
the application can only do a half-hearted job in difficult cases.
Such a difficult case might involve detecting that a subgraph containing
cycles has become detached from its root ... the case where reference
counting does not work.  My argument is that the difference between a
perfect job and imperfect job may be enough to cause the program to die.

I therefore maintain that my "may use more storage" point is CORRECT.

Finally (sigh) I wrote:
>> Finally, don't forget that the case where condition a) is not true; i.e.
>> some of the dynamically allocated ADT instance are passed out of scope
>> either explicitly (as a result) or implicitly (by side-effect).

Bill replies:
> Which can't happen unless either the applications programmer is 
> using pointers directly (naughty naughty), or something called by the
> application programmer (in effect, an extension of the application
> programmer) is doing it on his/her behalf.  In the latter case, we
> this presumably is in accordance with the called unit's specification, 
> and hence remains the fault of the applications programmer.

Sigh.

> The rule is simple: Leave the use of pointers to ADT implementors,
> and simply reuse the code they produce.  Exploit to the absolute 
> fullest the hard guarantees (proper space management, serializability, 
> recoverability, concurrent processing, etc.) that the ADT implementors
> worked so hard to provide you with, and thy Manager will be pleased.

Except that ADT implementors haven't because it is impossible.  And my
and their Managers had damn well better not start asking the impossible, 
'cos it will be on HIS head when we can't deliver!  (Don't worry, I will
have asked for a transfer ... or resigned by then.)

-- Steve