Article View: comp.sw.components
Article #149Re: List ADT example
From: Stephen Crawley
Date: Mon, 25 Sep 1989 16:44
Date: Mon, 25 Sep 1989 16:44
94 lines
4554 bytes
4554 bytes
Bill Wolfe writes:
>
> When you make your instantiation of the list type for objects of
> type A, you must fulfill the instantiation requirements. This will
> normally include supplying assignment and destruction procedures for
> objects of type A. If you send an object into the list, the assignment
> procedure will be used to create a resident copy. If you direct the
> removal of an object from the list, the destruction procedure will be
> used to destroy it. (See Booch, "Software Components with Ada")
>
First objection: I don't want to put a copy of the instance of A into the list
twice. I want to put the SAME instance of A into the list twice. If
A is a mutable type (i.e. has operations that can change a value) this
is a significant semantic difference.
Actually, though you SAY "make a resident copy [of the object]" I think
you MEAN something slightly different; "make a resident copy of the ref
to the object". Unfortunately, Ada makes a distinction between pointers
and non-pointers and this makes such things hard to describe concisely.
I'll assume you meant this, and also that the object has an internal
reference count that is incremented by the ADT's "assign" and decremented
by its "destroy". (The ref count is essential if an object is to be appear
more than once in a list)
Second objection: You do not say how the assign and destruct operations
get invoked when an instance of A returned by the LIST ADT to the
application. In general this requires some cooperatation on the part
of the application.
In ADA it seems that by declaring A in the ADT as a "limited private" type
the ADT can force the application to cooperate as far as assignment is
concerned. (Since limited private types do not support ANY operations except
for those declare by the PACKAGE, the application programmer can be forced
to apply the ASSIGN or DESTRUCT operation to the result of every A operation
that returns an A instance in order to get his program to type check.)
However, I can't see how the application is forced to call DESTROY on an A
variable when its declaration scope exits. [Please correct me if I am wrong
.. I am NOT an ADA expert.]
If this is the case, then it is a trivial matter to generate an example
where correct storage management depends on the application programmer
not making a mistake. In other words, this is not a correct solution.
---
The ADA partial solution to storage management for lists strikes me as
ugly. For every ADT A, the corresponding PACKAGE needs to declare two
types and a bunch of extra operators (ASSIGN, DESTROY and others that
are forced on us by exporting the type of A as a LIMITED PRIVATE) Finally,
since := can't be overloaded, the programmer has to use an awkward idiom
to assign an A instance to a variable.
Then there is the issue of efficiency. [After all, efficiency IS the
reason we are not using GC'ed storage...] Every time an instance of
the ADT A is assigned, we execute the ASSIGN operator which would be
coded something like
TYPE
A_obj = RECORD [
ref_count: int,
...
]
A = POINTER TO A_obj
-- Assign: updates the A variable given by 'dest'
-- to hold the A object given by 'source'
assign = PROCEDURE (source: IN A, dest: IN OUT A)
IF dest ~= 'uninitialised' THEN
-- If there is already a A value in 'dest', decrement its ref count.
dest^.ref_count := dest^.ref_count - 1
IF dest^.ref_count = 0 THEN
-- deallocate dest^ and all of its fields.
END
END
source^.ref_count := source^.ref_count + 1
dest := source
END assign
That is a LOT of work for a simple assignment!
Contrast it with the GC'ed case where assignment is probably 1 machine
instruction unless you are using some useless reference counting garbage
collection scheme.
If the ratio of list access to list building operations is large enough
(I'd guess maybe 10 to 1 if ASSIGN isn't expanded inline), it will be
MORE EFFICIENT TO USE GARBAGE COLLECTION.
-- Steve
Technical Details
Message-ID:
<915@scaup.cl.cam.ac.uk>Path:
arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!gem.mps.ohio-state.edu!ginosko!uunet!mcsun!ukc!cam-cl!sccReferences:
<902@scaup.cl.cam.ac.uk> <6555@hubcap.clemson.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!gem.mps.ohio-state.edu!ginosko!uunet!mcsun!ukc!cam-cl!scc From: scc@cl.cam.ac.uk (Stephen Crawley) Newsgroups: comp.sw.components Subject: Re: List ADT example Message-ID: <915@scaup.cl.cam.ac.uk> Date: 25 Sep 89 16:44:36 GMT References: <902@scaup.cl.cam.ac.uk> <6555@hubcap.clemson.edu> Sender: news@cl.cam.ac.uk Organization: U of Cambridge Comp Lab, UK Lines: 94