Version 1.1 of ais/ai-00345.txt

Unformatted version of ais/ai-00345.txt version 1.1
Other versions for file ais/ai-00345.txt

!standard 3.04.03 (00)          03-08-07 AI95-00345/00
!class amendment 03-08-07
!status received 03-06-12
!priority Medium
!difficulty Hard
!subject Protected interfaces
!corrigendum 03.09.01(03)
!ACATS test

From: Randy Brukardt
Sent: Thursday, June 12, 2003  7:43 PM

Tucker wrote me:

Here is an article I have submitted to
the Ada User Journal.  It might be of interest
to ARG members.  Rather than filling all of their
mailboxes with it, I thought I would just fill
yours ;-).  Once you get it posted, could you send
out an e-mail with a URL pointing to it?


The article is posted at

Happy reading!

[Editor's note: This article proposes protected interfaces.]


From: Robert I. Eachus
Sent: Thursday, June 12, 2003  11:19 PM

I was interested to compare the three cyclic type structure proposals as
they appear in Tuck's examples.  They all occupy about the same volume
in number of lines, but the generalized incomplete type approach
definitely looks the cleanest/most Ada-like.  There are of course,
plenty of reasons why any one of the three proposals might turn out to
be problematical for other reasons, but I think this causes me to lean a
little more in the direction I was leaning anyway.

Oh, and the write-up of protected interfaces seems to me to be the best
argument for adding interfaces to the language.  I'll have to think
about it (a lot).  I like the idea of having all queue types match a
potentially tasking safe interface.  Some implementations could be
tasking safe and others assume they are only visible in a single thread.
  A wonderful extension to Ada as an expository language for algorithm
design.  Now all we have to do is figure out how to actually implement
it. ;-)


From: Pascal Leroy
Sent: Friday, June 13, 2003  11:03 AM

Is this really what Tucker is proposing?  The way I read his paper,
protected and non-protected interfaces are distinct beasts and do not
mix.  So if a queue has a protected interface, all of its
implementations have to be protected.  I might be misreading the intent
of course, it's hard to know without an AI.  But because the calling
conventions of protected and non-protected operations are vastly
different, I don't see how a class-wide type could indifferently
designate a protected or a non-protected implementation.


From: Tucker Taft
Sent: Friday, June 13, 2003  1:22 PM

I was not proposing mixing protected interfaces
and tagged interfaces.  That would seem to be
a bad idea, given that the semantics are so different.
I'm not sure exactly what Robert Eachus had in mind,
but if you want to mix protected and tagged, you
will have to "wrap" one in the other.


From: Robert I. Eachus
Sent: Friday, June 13, 2003  1:22 PM

I don't think it is what Tucker is proposing, and a pragma would be
useful.   But Tucker's proposal certainly allows what I am thinking of.
  Imagine two implementations of a protected (class-wide) type. One
version, say the parent is a "normal" protected object with all of the
necessary baggage to support say a queue which is accessed by different
threads/tasks.  With Tucker's proposal you can also provide a child
implementation which will fail in one of many ways, possibly by
deadlock, if it is actually called by two different tasks.  And maybe
another child that works fine with at most two callers, but can livelock
or deadlock with three or more.

It would be nice to have a pragma that told the compiler that "this
protected body assumes a single task," if only for documentation
purposes.  Even without it, the checks/overhead in the single thread
version should be low.  With a pragma, the compiler can choose a locking
implementation which has very low overhead for passing through, and a
much higher overhead--or even Program_Error--if a caller ever blocks.
The interface is identical, and any compilers that do lock checking
outside the protected object code don't need to change.

Let me give an example.  Suppose you have a protected object type that
provides serialized access to a disk file, perhaps of a Sequential_IO
file with a (Direct_IO) associated index.  (Reading or writing would
require several calls on the protected object.) The simple
implementation would allow only one transaction in process at a time.
(Begin_Transaction, Lookup, Read or Write, Close_Transaction.)  The more
complex implementation could allow for several transactions to be in
progress at the same time.  (File locking vs. record locking.)

The key point is that this effectively adds a capability to Ada that has
been there all along, but in general becomes too difficult to use.
Right now you can customize generics, but that requires preplaning to
provide the right generic formal parameters.  A good example of this
type of customization is providing different ">" operators as parameters
to a sort routine allows the same sort routine to be used to sort on
different keys.

But allowing for full generality is just not possible.  The original
implementor of the generic has to think of all the possible
customizations ahead of time, and provide the additional generic
parameters to accomplish it.  Does this sound something like the problem
with variant records that tagged types solved?  It does to me.
Fortunately, I think that the hard work has already been done by
existing compilers, what is needed is the (trivial?) bit of effort
required to permit programmers to provide alternate bodies for generics.

I'm working on writing this up.  Basically think of it as adding derived
generics to the language.  The "new" generic has the same interface as
its parent but provides a new body.  It might be nice to allow the new
body (assuming that the generic is a package) to call operations of the
parent, but I think it is adequate to allow/require the programmer to
create an instance of the parent generic if he wants to do that.


Questions? Ask the ACAA Technical Agent