[comp.lang.ada] Keys are references, too

bbadger@x102c.uucp (Badger BA 64810) (12/16/88)

In article <3861@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>From article <6702@june.cs.washington.edu>, by klaiber@june.cs.washington.edu (Alexander Klaiber):
>> Assume I maintain mailing-lists of people and I represent the lists by
>> pointers to objects representing one person each; i.e.
>> type person is (some adt)
>> type mailinglist is new list(person);
>> Now if I have more than one mailing-list, obviously I have structure-sharing: 
>> a given person may appear on more than one list. 
>
> No, this isn't structural sharing, because you are explicitly manipulating 
> a list of pointers.  Structural sharing occurs when you have two objects, 
> A and B, and making some modification to B causes a modification to A as 
> well, because they share a portion of their structure.  The structure
> of a pointer is simply the address field, and the address fields are not
> being shared.  Now if we had two ADTs, both implemented by *hidden*
> pointers, and assignment failed to result in a deep copy, then THAT 
> would be structural sharing. 
>
> In this particular instance, it would be best to store the key by which
> a person could be identified (social security number, for example) in
> the list, and then using the key to retrieve the current address from
> the Person database.  Thus, a mailing list would be a list of social
> security numbers. 
>   
>
>                                            Bill Wolfe
>
>                                    wtwolfe@hubcap.clemson.edu
Mr. Wolfe does not (here) recognize the social security number (SSN) as 
another form of access mechanism.  *Any* means by which a symbol can be 
introduced to stand in as the ``name'' of the actual object will introduce 
the ability to ``share'' the object by mentioning the name in two places.  
Just because the SSN is not a memory address pointer, does not mean that 
sharing is not taking place.  (As an aside, the Ada LRM is careful not to call
access types ``pointers'' for a similar reason:  access types may turn out
to *not* be implemented as a memory pointer.)

Another key thing that Mr. Wolfe does not address is the problem of deciding
*when* to destroy an object.  Sure, it's easy enough, in most cases, to write 
a destruction routine, but you can't always wait until passing out of the 
scope of the visibility of the ADT to clean up.  This is where all the 
reference counts and other garbage collection mechanisms come in:  determining
that it is *SAFE* to reclaim storage.  Mr. Wolfe's database design has the 
same problem:  It's easy to remove the personnel record, but you may only 
do so when the SSN is not referenced any more.  

Leaving this decision up to the clients of the ADT, say by providing explicit
DESTROY(X) calls, just pushes this burden on the programmer of the client.  
In many cases, there is a clear and efficient way to determine when it is 
safe to destroy objects.  Fine!  Those cases can be explicitly managed by 
the programmer. A good garbage collector should not waste time  attemting 
to garbage-collect over programmer-managed data.  Perhaps a pragma(NO_GC,type);
would be helpful to the compiler.  

You have to show that GC is *never* worthwhile to justify *prohibiting* it 
from the language.  It seems to me that investing a lot of serious effort to 
get a really good GC algorithm built into the language would be much better 
than expecting "average" programmers to correctly implement proper storage 
reclamation for each ADT they'd like to use which requires memory allocation.
Even if not every compiler vender has ``the world's best'' memory reclamation,
it will be easier to select one that does, based on professional reviews, 
than to implement it yourself.



Bernard A. Badger Jr.	407/984-6385          |``Use the Source, Luke!''
Secure UNIX Products                          |It's not a bug; it's a feature!
Harris GISD, Melbourne, FL                    |Buddy, can you paradigm?
Internet: bbadger@cobra@trantor.harris-atd.com|Recursive:  see Recursive.

billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (12/19/88)

From article <1407@trantor.harris-atd.com>, by bbadger@x102c.uucp (Badger BA 64810):
> Mr. Wolfe does not (here) recognize the social security number (SSN) as 
> another form of access mechanism.  *Any* means by which a symbol can be 
> introduced to stand in as the ``name'' of the actual object will introduce 
> the ability to ``share'' the object by mentioning the name in two places.  

    If I have an object A, and pointers to that object P1 and P2, then
    I have three distinct objects, none of which share structure.

    If I have objects B and C, such that a modification to B results also
    in a modification of C, then this is structural sharing.  

> Another key thing that Mr. Wolfe does not address is the problem of deciding
> *when* to destroy an object.  Sure, it's easy enough, in most cases, to write 
> a destruction routine, but you can't always wait until passing out of the 
> scope of the visibility of the ADT to clean up.  

    This is why users can explicitly call DESTROY when the object is 
    no longer needed.

> Mr. Wolfe's database design has the 
> same problem:  It's easy to remove the personnel record, but you may only 
> do so when the SSN is not referenced any more.  

    Not true.  If the SSN refers to a person who is dead, then that fact 
    can be delivered as the database's response.  If the SSN refers to a
    person who has been deleted from or never existed in the database, then
    this can be delivered as the database's response, perhaps by raising an
    exception.  The database manager must decide how keys are to be managed, 
    and users of those keys must follow the database manager's directives.

> Leaving this decision up to the clients of the ADT, say by providing explicit
> DESTROY(X) calls, just pushes this burden on the programmer of the client.  

    If the programmer wishes to maximize space efficiency, explicit calls
    to DESTROY can be made when appropriate.  The block exit mechanism
    provides a convenient mechanism by which this directive can be given
    implicitly but unambiguously, with precisely known timing.

> It seems to me that investing a lot of serious effort to 
> get a really good GC algorithm built into the language would be much better 
> than expecting "average" programmers to correctly implement proper storage 
> reclamation for each ADT they'd like to use which requires memory allocation.

    Implementing proper storage allocation is the responsibility of the
    person who designs the ADT.  I think average, below average, and
    barely-above-brain-dead programmers can all comprehend the fact that
    objects must be both created and destroyed; they are created upon 
    declaration, and destroyed either by calling DESTROY or as an implicit
    consequence of block exit.

> Even if not every compiler vender has ``the world's best'' memory reclamation,
> it will be easier to select one that does, based on professional reviews, 
> than to implement it yourself.

    OK, all those who think it's just TERRIBLE to have to actually program 
    for reuseability can *purchase* generic ADTs, a/k/a software components.

    Then you can select the components you need, based on professional
    reviews, rather than implementing them yourself.  (Satisfied?)

    Wizard Software and Lib Systems are two vendors which supply such ADTs;
    anyone considering such a purchase should seek out professional reviews,
    since I write my own ADTs and therefore I have absolutely no experience 
    with and do not in any way endorse either firm's products.

    I might add that Jean Ichbiah explicitly predicted, long ago, the
    emergence of a software components industry, based upon the generic
    features of the (then-new) Ada language.  Slowly but surely, his 
    prediction is being fulfilled.



                                            Bill Wolfe

                                    wtwolfe@hubcap.clemson.edu