comp.lang.ada
 help / color / mirror / Atom feed
* "access constant" discriminant
@ 2003-02-10  8:26 tmoran
  2003-02-10 14:43 ` Frank J. Lhota
                   ` (3 more replies)
  0 siblings, 4 replies; 34+ messages in thread
From: tmoran @ 2003-02-10  8:26 UTC (permalink / raw)


Can this be done?  How?



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10  8:26 "access constant" discriminant tmoran
@ 2003-02-10 14:43 ` Frank J. Lhota
  2003-02-10 18:57   ` tmoran
  2003-02-10 19:26 ` Robert A Duff
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 34+ messages in thread
From: Frank J. Lhota @ 2003-02-10 14:43 UTC (permalink / raw)


What is it that you want to do?





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10 14:43 ` Frank J. Lhota
@ 2003-02-10 18:57   ` tmoran
  2003-02-15 19:17     ` Richard Riehle
  2003-02-20  2:20     ` Matthew Heaney
  0 siblings, 2 replies; 34+ messages in thread
From: tmoran @ 2003-02-10 18:57 UTC (permalink / raw)


>What is it that you want to do?
   In the case at hand, I'm using the idiom of a limited controlled type
whose initialization/finalization grabs/releases a resource lock, and the
access discriminant tells which resource.
  type Lock_Type(Resource : access Resource_Type) is new
  Ada.Finalization.Limited_Controlled with ...
and later
  Locker : Lock_Type(Resource'unchecked_access);
  ...
But this won't work when Resource is an "in" parameter, eg a function
parameter.  I suppose Ada is telling me that grabbing a lock is
effectively modifying the resource, and thus something that shouldn't be
done when the resource is an "in" parameter, but the question remains, why
can't one say
  type Lock_Type(Resource : access constant Resource_Type) ...
Did the designers foresee and forestall my use with a function?



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10  8:26 "access constant" discriminant tmoran
  2003-02-10 14:43 ` Frank J. Lhota
@ 2003-02-10 19:26 ` Robert A Duff
  2003-02-10 22:27 ` Rod Chapman
  2003-02-20  2:17 ` Matthew Heaney
  3 siblings, 0 replies; 34+ messages in thread
From: Robert A Duff @ 2003-02-10 19:26 UTC (permalink / raw)


tmoran@acm.org writes:

> Can this be done?  How?

Unfortunately, no.  AI's 231 and 230 attempt to correct this language
design flaw, and some related things.  See:

http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00231.TXT

and

http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-00230.TXT

- Bob



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10  8:26 "access constant" discriminant tmoran
  2003-02-10 14:43 ` Frank J. Lhota
  2003-02-10 19:26 ` Robert A Duff
@ 2003-02-10 22:27 ` Rod Chapman
  2003-02-11  2:00   ` Jeffrey Carter
  2003-02-20  2:28   ` Matthew Heaney
  2003-02-20  2:17 ` Matthew Heaney
  3 siblings, 2 replies; 34+ messages in thread
From: Rod Chapman @ 2003-02-10 22:27 UTC (permalink / raw)


tmoran@acm.org wrote in message news:<lnJ1a.50689$SD6.3473@sccrnsc03>...
> Can this be done?  How?

A great shame that it can't.  From the viewpoint of a static analysis
tool, this is dreadful, since access parameters don't specify whether
the referenced objected is intended to be referenced, updated, or both - this
severely limits our ability to do information flow analysis in the presence
of access parameters, which needs
such information to be available as part of a subprogram's specifiction
if it to used usefully and efficiently implemented.  In light of this, SPARK
currently excludes access parameters.

(In SPARK, we have parameter modes as normal, but we extend a subprogram's
specification to include a list of all global data and their import/export
modes via the global annotation.  This makes IFA efficient, since we don't
need to look inside the body - all the info we need is on the spec.)

If access parameters were allowed to specify such information (e.g. "access in",
"access out" and "access in out") this would be a great help.  I remember
mentioning this to Tucker at SigAda and he took a note of it - not
sure if this issue has made it into any of the current AI's, though...

  - Rod



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10 22:27 ` Rod Chapman
@ 2003-02-11  2:00   ` Jeffrey Carter
  2003-02-20  2:28   ` Matthew Heaney
  1 sibling, 0 replies; 34+ messages in thread
From: Jeffrey Carter @ 2003-02-11  2:00 UTC (permalink / raw)


Rod Chapman wrote:
> specifiction

That's when the specification lies, right? :)

-- 
Jeff Carter
"Every sperm is sacred."
Monty Python's the Meaning of Life




^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10 18:57   ` tmoran
@ 2003-02-15 19:17     ` Richard Riehle
  2003-02-15 19:59       ` Larry Kilgallen
  2003-02-20  2:23       ` Matthew Heaney
  2003-02-20  2:20     ` Matthew Heaney
  1 sibling, 2 replies; 34+ messages in thread
From: Richard Riehle @ 2003-02-15 19:17 UTC (permalink / raw)


tmoran@acm.org wrote:

>
> why can't one say
>   type Lock_Type(Resource : access constant Resource_Type) ...
> Did the designers foresee and forestall my use with a function?

I raised an issue about this from time to time in this forum, but in
a sligthly different way.

We have,
                 type Reference is access all some-type;

and

                type Reference is acess constant some-type;

A function may have a an access parameter, which almost has in
semantics.   However,  it is possible to modify a component of
an access parameter.  I would like the option of preventing that
with,

               function F (X : access constant parameter-name) return
some-type;

This would make it illegal for the function to modify the components of
an access parameter.   Without the word constant, one could still modify
such components, but including it would make absolutely clear, in the
contract, that such side-effects would be impossible.

Richard Riehle







^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-15 19:17     ` Richard Riehle
@ 2003-02-15 19:59       ` Larry Kilgallen
  2003-02-15 23:53         ` Richard Riehle
                           ` (2 more replies)
  2003-02-20  2:23       ` Matthew Heaney
  1 sibling, 3 replies; 34+ messages in thread
From: Larry Kilgallen @ 2003-02-15 19:59 UTC (permalink / raw)


In article <3E4E9248.3E71D984@adaworks.com>, Richard Riehle <richard@adaworks.com> writes:

> A function may have a an access parameter, which almost has in
> semantics.   However,  it is possible to modify a component of
> an access parameter.  I would like the option of preventing that
> with,
> 
>                function F (X : access constant parameter-name) return
> some-type;
> 
> This would make it illegal for the function to modify the components of
> an access parameter.   Without the word constant, one could still modify
> such components, but including it would make absolutely clear, in the
> contract, that such side-effects would be impossible.

Why is it necessary to have the parameter be an access type ?



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-15 19:59       ` Larry Kilgallen
@ 2003-02-15 23:53         ` Richard Riehle
  2003-02-16  1:50           ` Eric G. Miller
  2003-02-20  2:23         ` Matthew Heaney
  2003-02-20 17:34         ` Stephen Leake
  2 siblings, 1 reply; 34+ messages in thread
From: Richard Riehle @ 2003-02-15 23:53 UTC (permalink / raw)


Larry Kilgallen wrote:

> Why is it necessary to have the parameter be an access type ?

Good question.  Consider this package,

        package Side_Effect_Experiment is

             type Item_Type is private;
             type Reference is access all Item_Type;
             procedure Create (Data : in out Item_Type);
             function Is_Valid (Data :  in Item_Type) return Boolean;
             function Is_Valid (Data : in Reference)  return Boolean;
             function Is_Valid (Data : access Item_Type) return Boolean;
       private
             type Item_Type is record
                  ID                : Natural := 0;
                  Description : String(1..20) := (others => ' ');
                  Valid           : Boolean := False;
             end record;
      end Side_Effect_Experiment;

with this corresponding package body,

    package body Side_Effect_Experiment is

        procedure Create (Data : in out Item_Type) is
        begin
           null;
       end Create;

       function Is_Valid (Data :  in Item_Type) return Boolean is
       begin
            Data.Valid := True;      -- not valid for in parameter
            return Data.Valid;
       end Is_Valid;

       function Is_Valid (Data : in Reference) return Boolean is
       begin
            Data.Valid := True;
            return Data.Valid;
      end Is_Valid;

      function Is_Valid (Data : access Item_Type) return Boolean is
      begin
           Data.Valid := True;
           return Data.Valid;
     end Is_Valid;

  end Side_Effect_Experiment;

Note that the side-effect cannot happen when we have a normal in
parameter.  However,  it can occur with any variation of an access
type parameter.   By adding syntax to the function such as,

          constant function Is_Valid(Data : access Item_Type) return Boolean;
or
          function Is_Valid (Data : access constant Item_Type) return Boolean;

the compiler would be able to note the attempt at a side-effect and prevent
it.

Richard Riehle









^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-15 23:53         ` Richard Riehle
@ 2003-02-16  1:50           ` Eric G. Miller
  0 siblings, 0 replies; 34+ messages in thread
From: Eric G. Miller @ 2003-02-16  1:50 UTC (permalink / raw)


In article <3E4ED2FC.3310564A@adaworks.com>, Richard Riehle wrote:
> Larry Kilgallen wrote:
> 
>> Why is it necessary to have the parameter be an access type ?

Not long ago, I wrote a C library wrapper that takes advantage of
being able to modify the contents of a function via an access 
parameter.  Being able to specify "constant" seems like a good
thing for safety and for clarifying the "contract" in the API.

The "C" library has functions like:

typedef struct Foo { /* whatever */} Foo;
long Get_Foo (Foo *);
long Set_Foo (Foo);

So, the Ada wrapper is like:

type Foo is record
   -- whatever...
end record;
pragma Convention (Convention => C_Pass_By_Copy, Entity => Foo);

function Get_Foo (Self : access Foo) return Error_Code;
pragma Import (Convention    => C,
	       Entity        => Get_Foo,
	       External_Name => "Get_Foo");

function Set_Foo (Self : Foo) return Error_Code;
pragma Import (Convention    => C,
	       Entity        => Set_Foo,
	       External_Name => "Set_Foo");


But, maybe there's a function like:

#define FOO_NAME_LENGTH 42
typedef char Foo_Name[FOO_NAME_LENGTH];
long Get_Foo_Name (const Foo *, Foo_Name);

So, I might want a wrapper function that mirrors this:

Foo_Name_Length : constant := 42;
subtype Foo_Name is C.Char_Array(1..Foo_Name_Length);
function Get_Foo_Name (Self : access constant Foo; 
                       Name : access Foo_Name) return Error_Code;
pragma Import (Convention    => C,
	       Entity        => Get_Foo_Name,
	       External_Name => "Get_Foo_Name");

Seems like a reasonable thing.  The downside of pointers to constant
parameters is functions that are declared using "constant", calling
functions or procedures that aren't so marked even if such functions
actually treat the parameter as a constant.  I've encountered this
enough times in the "C" world to see that it diminishes the utility
of "const".  Still, overall it's probably better to have it available
than not.

-- 
echo ">gra.fcw@2ztr< eryyvZ .T pveR" | rot13 | reverse



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10  8:26 "access constant" discriminant tmoran
                   ` (2 preceding siblings ...)
  2003-02-10 22:27 ` Rod Chapman
@ 2003-02-20  2:17 ` Matthew Heaney
  3 siblings, 0 replies; 34+ messages in thread
From: Matthew Heaney @ 2003-02-20  2:17 UTC (permalink / raw)


tmoran@acm.org wrote in message news:<lnJ1a.50689$SD6.3473@sccrnsc03>...
> Can this be done?  How?

I discuss how in my design patterns tutorial, which I'll be giving in
Toulouse in June.

You basically have two options:

1) If your type is limited, you can use the Rosen Trick:


type T;

type Handle_Type (O : access T) is 
   limited null record;

type T is
   limited record
      H : Handle_Type (T'Access);
      <other components here>
   end record;

Now you can do this:

procedure Op (Read_Only : in T) is
 
   Read_Write : T renames Read_Only.H.O.all;
begin
   <modify Read_Write as necessary>
end;

This is completly portable and safe.


2) If your type isn't limited, you can't use the Rosen Trick.  But you
can do something similar if you have a pass-by-reference type.

Tagged types are pass-by-reference, as are types with volatile
components.

So you do something like this:

type T is tagged record ... end record;

package P is
   new System.Address_To_Access_Conversions (T);

procedure Op (Read_Only : in T) is

   Pointer : constant P.Object_Pointer := 
      P.To_Pointer (Read_Only'Address);

   Read_Write : T renames Pointer.all;
begin
   <modify Read_Write as necessary>
end;


You might also be able to use the GNAT 'Unrestricted_Access attribute.

It is indeed unfortunate that method #2 requires that we circumvent
the type system just to cast away const.  The GNAT attribute has the
benefit that strong typing is preserved.

I acually use the Rosen Trick to implement the bounded vectors in the
Charles library.  Incredibly, types whose full view is limited aren't
implicitly aliased when passed as subprogram parameters (that's only
true for tagged types -- don't ask me why...), so you need to use the
Rosen Trick to get an aliased view.

http://home.earthlink.net/~matthewjheaney/charles/charles-vectors-bounded.html
http://home.earthlink.net/~matthewjheaney/charles/index.html



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10 18:57   ` tmoran
  2003-02-15 19:17     ` Richard Riehle
@ 2003-02-20  2:20     ` Matthew Heaney
  1 sibling, 0 replies; 34+ messages in thread
From: Matthew Heaney @ 2003-02-20  2:20 UTC (permalink / raw)


tmoran@acm.org wrote in message news:<3CS1a.55972$2H6.1357@sccrnsc04>...
> >What is it that you want to do?
>    In the case at hand, I'm using the idiom of a limited controlled type
> whose initialization/finalization grabs/releases a resource lock, and the
> access discriminant tells which resource.
>   type Lock_Type(Resource : access Resource_Type) is new
>   Ada.Finalization.Limited_Controlled with ...
> and later
>   Locker : Lock_Type(Resource'unchecked_access);
>   ...
> But this won't work when Resource is an "in" parameter, eg a function
> parameter.  I suppose Ada is telling me that grabbing a lock is
> effectively modifying the resource, and thus something that shouldn't be
> done when the resource is an "in" parameter, but the question remains, why
> can't one say
>   type Lock_Type(Resource : access constant Resource_Type) ...
> Did the designers foresee and forestall my use with a function?

If your resource is limited, then use the Rosen Trick, and add a
handle to the type's representation:

procedure Op (Resource : in Resource_Type) is

  Lock : Lock_Type (Resource.Handle.Resource);
begin

where Handle is 

type Handle_Type (Resource : access Resource_Type) is
   limited null record;

type Resource_Type is
   limited record 
      Handle : Handle_Type (Resource_Type'Access);
      ...
   end record;

If your resource type isn't limited, then you can safely use
Address_To_Access_Conversions the type is pass-by-reference.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-15 19:17     ` Richard Riehle
  2003-02-15 19:59       ` Larry Kilgallen
@ 2003-02-20  2:23       ` Matthew Heaney
  1 sibling, 0 replies; 34+ messages in thread
From: Matthew Heaney @ 2003-02-20  2:23 UTC (permalink / raw)


Richard Riehle <richard@adaworks.com> wrote in message news:<3E4E9248.3E71D984@adaworks.com>...
> tmoran@acm.org wrote:
> 
> 
> A function may have a an access parameter, which almost has in
> semantics.   However,  it is possible to modify a component of
> an access parameter.  I would like the option of preventing that
> with,
> 
> function F (X : access constant parameter-name) 
>   return some-type;
> 
> This would make it illegal for the function to modify the components of
> an access parameter.   Without the word constant, one could still modify
> such components, but including it would make absolutely clear, in the
> contract, that such side-effects would be impossible.


The "access constant" locution will probably be incorporated into a
future update of the language.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-15 19:59       ` Larry Kilgallen
  2003-02-15 23:53         ` Richard Riehle
@ 2003-02-20  2:23         ` Matthew Heaney
  2003-02-20 17:34         ` Stephen Leake
  2 siblings, 0 replies; 34+ messages in thread
From: Matthew Heaney @ 2003-02-20  2:23 UTC (permalink / raw)


Kilgallen@SpamCop.net (Larry Kilgallen) wrote in message news:<zwb0dJM87esk@eisner.encompasserve.org>...
> In article <3E4E9248.3E71D984@adaworks.com>, Richard Riehle <richard@adaworks.com> writes:
> 
> 
> Why is it necessary to have the parameter be an access type ?

Because operations that have access parameters are primitive for the
type, which means they're inherited during a derivation.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-10 22:27 ` Rod Chapman
  2003-02-11  2:00   ` Jeffrey Carter
@ 2003-02-20  2:28   ` Matthew Heaney
  2003-02-20  9:45     ` Lutz Donnerhacke
  1 sibling, 1 reply; 34+ messages in thread
From: Matthew Heaney @ 2003-02-20  2:28 UTC (permalink / raw)


rod.chapman@praxis-cs.co.uk (Rod Chapman) wrote in message news:<cf2c6063.0302101427.51b50e12@posting.google.com>...
> tmoran@acm.org wrote in message news:<lnJ1a.50689$SD6.3473@sccrnsc03>...
> > Can this be done?  How?
> 
> A great shame that it can't.  From the viewpoint of a static analysis
> tool, this is dreadful, since access parameters don't specify whether
> the referenced objected is intended to be referenced, updated, or both - this
> severely limits our ability to do information flow analysis in the presence
> of access parameters, which needs
> such information to be available as part of a subprogram's specifiction
> if it to used usefully and efficiently implemented.  In light of this, SPARK
> currently excludes access parameters.


Realize that what the spec says about subprogram parameter modes is
largely irrelevent in Ada.  If the type is limited, then the Rosen
Trick can be used to get a variable view of the object, no matter what
the spec says.

How does SPARK handle the Rosen Trick?



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-20  2:28   ` Matthew Heaney
@ 2003-02-20  9:45     ` Lutz Donnerhacke
  0 siblings, 0 replies; 34+ messages in thread
From: Lutz Donnerhacke @ 2003-02-20  9:45 UTC (permalink / raw)


* Matthew Heaney wrote:
> How does SPARK handle the Rosen Trick?

Spark disallow it.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-15 19:59       ` Larry Kilgallen
  2003-02-15 23:53         ` Richard Riehle
  2003-02-20  2:23         ` Matthew Heaney
@ 2003-02-20 17:34         ` Stephen Leake
  2003-02-21  0:42           ` Matthew Heaney
  2 siblings, 1 reply; 34+ messages in thread
From: Stephen Leake @ 2003-02-20 17:34 UTC (permalink / raw)


Kilgallen@SpamCop.net (Larry Kilgallen) writes:

> Why is it necessary to have the parameter be an access type ?

(as opposed to "in", I assume)

Because the body needs to call other functions that take access types
(that may beg the question, but it's the best I can do :).

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-20 17:34         ` Stephen Leake
@ 2003-02-21  0:42           ` Matthew Heaney
  2003-02-21 10:41             ` Lutz Donnerhacke
                               ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: Matthew Heaney @ 2003-02-21  0:42 UTC (permalink / raw)


Stephen Leake <Stephen.A.Leake@nasa.gov> wrote in message news:<uu1eyluui.fsf@nasa.gov>...
>
> Because the body needs to call other functions that take access types
> (that may beg the question, but it's the best I can do :).

Access parameters carry accessibility information around, to check
that an object in an outer scope doesn't refer to another object in an
inner scope.

These accessibility checks can be turned off using the
'Unchecked_Access attribute, or by using a pragma to suppress
Access_Check.

One example of the use of access parameters is the "multiple views"
idiom in Ada95, to effect the equivalent of multiple inheritance in
other languages.  For example, given a mechanism to store objects that
are "persistent":

   procedure Write 
     (Persistence : access Persistence_Type'Class);

then we can save any object that supports this view, like this:

   Some_Object : aliased T;
   ...
   Write (Persistence_View (Some_Object'Access));

The selector function would be written as:

  function Persistence_View 
   (Object : access T) return Persistence_Class_Access;

In the canonical model, type T would have an aliased component whose
type derives from Root_Persistence_Type, and the selector function is
implemented simply as:

   fuction Persistence_View 
     (Object : access T) return Persistence_Class_Access is
   begin
      return Object.Persistence_View'Access;
   end;

Here we see the reason why we passed an access parameter: it's because
we're returning an access value that designates one of our own
components.

The view component would be implemented like this:

   type Persistence_Type is
      new Root_Persistence_Type (Object : access T) with null record;

   type T is
      limited record
         Persistence_View : aliased Persistence_Type (T'Access);
         ...
      end record;

Presumably the Root_Persistence_Type has primitive operations for
writing an object into a stream, e.g.

   procedure Write 
     (Persistence : access Root_Persistence_Type;
      Stream      : in out Root_Stream_Type'Class) is abstract;

The Persisence_Type about would override the Write operation, to write
a T object into the stream.  It has visibility to the T object via its
access discriminant.

Access discriminants are very powerful.  No serious Ada95 program can
be written without them.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21  0:42           ` Matthew Heaney
@ 2003-02-21 10:41             ` Lutz Donnerhacke
  2003-02-21 20:21               ` Randy Brukardt
  2003-02-24 16:03               ` Matthew Heaney
  2003-02-21 15:03             ` Hyman Rosen
  2003-02-21 20:07             ` Randy Brukardt
  2 siblings, 2 replies; 34+ messages in thread
From: Lutz Donnerhacke @ 2003-02-21 10:41 UTC (permalink / raw)


* Matthew Heaney wrote:
> Access discriminants are very powerful.  No serious Ada95 program can
> be written without them.

If there is a serious program without access discriminants, let's call it a
Spark program, or trivial, ok?



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21  0:42           ` Matthew Heaney
  2003-02-21 10:41             ` Lutz Donnerhacke
@ 2003-02-21 15:03             ` Hyman Rosen
  2003-02-21 20:09               ` Randy Brukardt
  2003-02-21 21:33               ` Matthew Heaney
  2003-02-21 20:07             ` Randy Brukardt
  2 siblings, 2 replies; 34+ messages in thread
From: Hyman Rosen @ 2003-02-21 15:03 UTC (permalink / raw)


Matthew Heaney wrote:
> Access parameters carry accessibility information around, to check
> that an object in an outer scope doesn't refer to another object in an
> inner scope.

Do they actually carry this information around?
I thought that the language rules just prevented
such "inner" addresses from winding up in an
"outer" pointer, not that the pointers themselves
were "fat".




^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21  0:42           ` Matthew Heaney
  2003-02-21 10:41             ` Lutz Donnerhacke
  2003-02-21 15:03             ` Hyman Rosen
@ 2003-02-21 20:07             ` Randy Brukardt
  2003-02-24 19:11               ` Matthew Heaney
  2 siblings, 1 reply; 34+ messages in thread
From: Randy Brukardt @ 2003-02-21 20:07 UTC (permalink / raw)


Matthew Heaney wrote in message
<1ec946d1.0302201642.66eb93e5@posting.google.com>...

>Here we see the reason why we passed an access parameter: it's because
>we're returning an access value that designates one of our own
>components.


That reason being only that Ada doesn't support 'in out' parameters on
functions. If it did,

fuction Persistence_View
     (Object : in out T) return Persistence_Class_Access is
   begin
      return Object.Persistence_View'Access;
   end;

would work fine, and would be a lot easier to use as well.

But that's not going to happen, so we're stuck with terrible workarounds
like 'access' parameters.

             Randy.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 15:03             ` Hyman Rosen
@ 2003-02-21 20:09               ` Randy Brukardt
  2003-02-21 21:33               ` Matthew Heaney
  1 sibling, 0 replies; 34+ messages in thread
From: Randy Brukardt @ 2003-02-21 20:09 UTC (permalink / raw)


Hyman Rosen wrote in message <1045839826.87966@master.nyc.kbcfp.com>...
>Matthew Heaney wrote:
>> Access parameters carry accessibility information around, to check
>> that an object in an outer scope doesn't refer to another object in
an
>> inner scope.
>
>Do they actually carry this information around?
>I thought that the language rules just prevented
>such "inner" addresses from winding up in an
>"outer" pointer, not that the pointers themselves
>were "fat".


That's true for everything *except* access parameters. They actually are
required to carry a runtime accessibility level. (That's usually part of
the parameter, not part of the access.) That's another reason to avoid
access parameters, because they have more overhead than an in or in out
parameter.

          Randy.





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 10:41             ` Lutz Donnerhacke
@ 2003-02-21 20:21               ` Randy Brukardt
  2003-02-23 12:22                 ` Simon Wright
                                   ` (2 more replies)
  2003-02-24 16:03               ` Matthew Heaney
  1 sibling, 3 replies; 34+ messages in thread
From: Randy Brukardt @ 2003-02-21 20:21 UTC (permalink / raw)


Lutz Donnerhacke wrote in message ...
>* Matthew Heaney wrote:
>> Access discriminants are very powerful.  No serious Ada95 program can
>> be written without them.
>
>If there is a serious program without access discriminants, let's call
it a
>Spark program, or trivial, ok?

Claw doesn't use access discriminants. That's in large part because they
cause limited 'poisoning', as they're restricted to limited types. We
prefered to use Adjust to make assignment work properly.

Indeed, I'm not aware of any real Ada program, serious or otherwise,
that actually uses access discriminants. I know that they were buggy in
Janus/Ada until very recently, and we never received any bug reports on
them. So, as a practical matter, these are a very marginal feature of
Ada with very limited uses.

In any case, Matt's statement would probably have been better if it
said:

Access discriminants are very powerful.  They are very much
underutilized, probably because hardly anybody understands them.

Sweeping statements about programming style are not likely to be
helpful. I tend to feel about finalization like Matt apparently does
about access discriminants, but the only time I would say something like
"No serious Ada program can be written without them." is when I'm
looking for fight. Even though I believe that is true, I'm well aware
that there are many, many Ada projects which have an irrational fear of
finalization, and to characterize them as not being "serious" is not
likely to make any friends.

         Randy.







^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 15:03             ` Hyman Rosen
  2003-02-21 20:09               ` Randy Brukardt
@ 2003-02-21 21:33               ` Matthew Heaney
  1 sibling, 0 replies; 34+ messages in thread
From: Matthew Heaney @ 2003-02-21 21:33 UTC (permalink / raw)


Hyman Rosen <hyrosen@mail.com> wrote in message news:<1045839826.87966@master.nyc.kbcfp.com>...
> Matthew Heaney wrote:
> > Access parameters carry accessibility information around, to check
> > that an object in an outer scope doesn't refer to another object in an
> > inner scope.
> 
> Do they actually carry this information around?
> I thought that the language rules just prevented
> such "inner" addresses from winding up in an
> "outer" pointer, not that the pointers themselves
> were "fat".

Access parameters carry accessibilty information around (not all
checks can be done statically).

Note that named access types do *not* carry the same information.  

When an access check fails at run-time, it's often because you're
assigning the value of an access parameter to an access object. 
That's why you sometimes have to do the assignment using
'Unchecked_Access instead.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 20:21               ` Randy Brukardt
@ 2003-02-23 12:22                 ` Simon Wright
  2003-02-24  7:06                 ` Dale Stanbrough
  2003-02-24 18:58                 ` Matthew Heaney
  2 siblings, 0 replies; 34+ messages in thread
From: Simon Wright @ 2003-02-23 12:22 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> Indeed, I'm not aware of any real Ada program, serious or otherwise,
> that actually uses access discriminants. I know that they were buggy
> in Janus/Ada until very recently, and we never received any bug
> reports on them. So, as a practical matter, these are a very
> marginal feature of Ada with very limited uses.

Very useful for records with task/protected type components, of
course!

(and I think my current project is fairly serious ..)



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 20:21               ` Randy Brukardt
  2003-02-23 12:22                 ` Simon Wright
@ 2003-02-24  7:06                 ` Dale Stanbrough
  2003-02-24 18:58                 ` Matthew Heaney
  2 siblings, 0 replies; 34+ messages in thread
From: Dale Stanbrough @ 2003-02-24  7:06 UTC (permalink / raw)


Randy Brukardt wrote:

> Claw doesn't use access discriminants. That's in large part because they
> cause limited 'poisoning', as they're restricted to limited types.

I call it the "Midas touch".

dale



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 10:41             ` Lutz Donnerhacke
  2003-02-21 20:21               ` Randy Brukardt
@ 2003-02-24 16:03               ` Matthew Heaney
  1 sibling, 0 replies; 34+ messages in thread
From: Matthew Heaney @ 2003-02-24 16:03 UTC (permalink / raw)


Lutz Donnerhacke <lutz@iks-jena.de> wrote in message news:<slrnb5c0ih.nq.lutz@taranis.iks-jena.de>...
> * Matthew Heaney wrote:
> > Access discriminants are very powerful.  No serious Ada95 program can
> > be written without them.
> 
> If there is a serious program without access discriminants, let's call it a
> Spark program, or trivial, ok?

What I meant was that access discriminants are the sine qua non of
Ada95 programming.  If you're not using them, you're losing something
essential, not accidental (per se vs. per accidens), about an Ada95
program.

Of course, this idiom is just a reification of a more general design
pattern called the "Adapter Pattern," or more specifically an "Object
Adapter."

It shows up in myriad languages.  You often see C++ written like this:

   X x;
   ...
   Y y(&x);

where the object y is bound to object x.  Class Y would be implemented
as

class Y
{
   X* const p
public:
   Y(X* pp) : p(pp) {}
   //...
private:
   Y& operator=(const Y&);
   Y(const Y&);
};

This shows up even in some Ada95 iterator implementations:

   Iter : Iterator_Type (Container'Access);

Here, you're viewing a container object through an iterator object.  

Of course, the effect of an object adapter can probably be implemented
sans access discriminants (persumably that is the case in SPARK), but
I don't consider these alternate locutions as elegant as an access
discriminant.

In your case you lose access discriminants in order to gain provable
correctness -- which is of course the correct tradeoff.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 20:21               ` Randy Brukardt
  2003-02-23 12:22                 ` Simon Wright
  2003-02-24  7:06                 ` Dale Stanbrough
@ 2003-02-24 18:58                 ` Matthew Heaney
  2003-02-24 21:05                   ` Randy Brukardt
  2 siblings, 1 reply; 34+ messages in thread
From: Matthew Heaney @ 2003-02-24 18:58 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> wrote in message news:<v5d2m6pi5q3tef@corp.supernews.com>...
> 
> Claw doesn't use access discriminants. That's in large part because they
> cause limited 'poisoning', as they're restricted to limited types. We
> prefered to use Adjust to make assignment work properly.

This may simply reflect a philosophical difference about whether types
should be limited or non-limited.  Certainly I have never agreed with
the CLAW decision to make window types non-limited, and to me a
non-limited window is completely wacky.

 
> Access discriminants are very powerful.  They are very much
> underutilized, probably because hardly anybody understands them.

I could make this argument about any language feature.

For example, when I was using Ada83, my experience was that many Ada
programmers never really understood what a private type was.  There
were many Ada83 programmers who didn't really grok the whole
object-oriented programming thing.

Another example: I worked on the F22 project for while, at Hughes.  No
one in the company seemed to know that you could return an
unconstrained array from a function:

   declare
      S : constant String := Name (File);
   begin

The problem was that Ada83 required the object to be marked as
"constant," so when the declaration

   declare
      S : String := Name (File);
   begin

didn't compile, everyone assumed that this meant you must return a
constrained array.  Of course this is incorrect -- but why didn't
anyone realize this?

I have observed a similar phenomenon among Ada95 programmers.  There
are many aspects of the Ada95 language with which many programmers are
unfamiliar.

For example, I gave a talk in London, and declared a private operation
that took the tagged type as an access parameter.  No one seemed to
realize that operations that accept the type as an access parameter
are primitive, and therefore dispatch when the parameter has type
T'Class.

Another of the speakers was talking about the problems he was having
with Unchecked_Access.  As it turns out, neither he nor anyone else in
his company knew that tagged types are passed by reference in Ada95. 
He was trying to prevent the "slicing" that can occur in C++ (and
which he thought would happen in Ada95 too), so he was declaring all
the type parameters using a named access type.  Of course, this is
incorrect, but why didn't anyone realize that tagged types are passed
by reference?


> Sweeping statements about programming style are not likely to be
> helpful. I tend to feel about finalization like Matt apparently does
> about access discriminants, but the only time I would say something like
> "No serious Ada program can be written without them." is when I'm
> looking for fight. Even though I believe that is true, I'm well aware
> that there are many, many Ada projects which have an irrational fear of
> finalization, and to characterize them as not being "serious" is not
> likely to make any friends.

Perhaps it was my use of the word "serious" that was confusing.  I
should have said "essential," with the same sense that Fred Brooks
used in his famous paper "Essence and Accidents in Software
Engineering."

http://atheism.about.com/library/glossary/general/bldef_essence.htm

C++ doesn't require you to use classes, but if you don't, it would be
a stretch to say that you're programming in "C++."  Really, you're
using a C++ compiler to compile a C program.  This is not necessarily
a bad thing -- after all, C++ gives you better compile-time error
checking and type-safe linkage.  But to not use classes you'd be
losing something "essential" to C++ programming.

The use of access discriminants in Ada95 is exactly analogous.  For
example, how would you add controlled-ness to a (tagged) type that is
part of type hierarchy that isn't already controlled?  The only way I
know is to do this:

   type NT is new T with private;
   ...
private
   type Control_Type (O : access NT) is
      new Limited_Controlled with null record;

   type NT is new T with record
      Control : Control_Type (NT'Access);
      ...
   end record;

This is an important Ada95 idiom with which every Ada95 needs to be
thoroughly familiar.  This idiom and others like it is why I
characterize access discriminants as "essential" (again, "per se" vs.
"per accidens") to programming in Ada95.



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-21 20:07             ` Randy Brukardt
@ 2003-02-24 19:11               ` Matthew Heaney
  2003-02-24 21:17                 ` Randy Brukardt
  0 siblings, 1 reply; 34+ messages in thread
From: Matthew Heaney @ 2003-02-24 19:11 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> wrote in message news:<v5d1sfo9ib2df9@corp.supernews.com>...
> Matthew Heaney wrote in message
> <1ec946d1.0302201642.66eb93e5@posting.google.com>...
> 
> >Here we see the reason why we passed an access parameter: it's because
> >we're returning an access value that designates one of our own
> >components.
> 
> 
> That reason being only that Ada doesn't support 'in out' parameters on
> functions. If it did,
> 
> fuction Persistence_View
>      (Object : in out T) return Persistence_Class_Access is
>    begin
>       return Object.Persistence_View'Access;
>    end;
> 
> would work fine, and would be a lot easier to use as well.

No -- this would be the wrong way to implement the multiple views
idiom.  You really do want to make explicit the fact that the object
is being aliased.

For example, in C++ I could do this:

  X x;
  Y y(x);

and implement Y this way:

class Y
{
   X& x;
public:
   Y(X& xx) : x(xx) {}
   //...
private:
   Y(const Y&);
   Y& operator=(const Y&);
};

but that would be entirely misleading, even if it's "easier" to
declare a Y object.  It's better to implement Y's ctor using an
explicit pointer:

class Y
{
   X& x;
public:
   Y(X* px) : x(*px) {}
private:
   Y(const Y&);
   Y& operator=(const Y&);
};

and then say:

  X x;
  Y y(&x);

Which makes it identical to how you'd say it in Ada95.  So this is not
really an Ada issue.

 
> But that's not going to happen, so we're stuck with terrible workarounds
> like 'access' parameters.

Access parameters have other uses besides getting around the lack of
inout mode for function parameters.  For example, operations that
accept a user-defined type as an access parameter are primitive for
the type, and hence are inherited in a derivation.  And an access
parameter means you don't have to say Op (O.all) everywhere.

However, we are in agreement that not having inout mode for functions
is a ridiculous restriction, since functions in Ada95 do modify their
arguments (the language just doesn't let you *say* that you do).



^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-24 18:58                 ` Matthew Heaney
@ 2003-02-24 21:05                   ` Randy Brukardt
  2003-02-25 14:15                     ` Frank J. Lhota
  0 siblings, 1 reply; 34+ messages in thread
From: Randy Brukardt @ 2003-02-24 21:05 UTC (permalink / raw)


Matthew Heaney wrote in message
<1ec946d1.0302241058.88ca487@posting.google.com>...
>"Randy Brukardt" <randy@rrsoftware.com> wrote in message
news:<v5d2m6pi5q3tef@corp.supernews.com>...
>>
>> Claw doesn't use access discriminants. That's in large part because
they
>> cause limited 'poisoning', as they're restricted to limited types. We
>> prefered to use Adjust to make assignment work properly.
>
>This may simply reflect a philosophical difference about whether types
>should be limited or non-limited.  Certainly I have never agreed with
>the CLAW decision to make window types non-limited, and to me a
>non-limited window is completely wacky.


That's a consequence of our no access type philosophy. So many people
seem to think that O-O means references, and that simply is not true in
Ada. The result of our "wackiness" is that you only need to explicitly
use access types when you need dynamic (and non-stack-based) allocation
of windows. Very few Claw programs have access to windows in them.

If I was doing it over, I'd probably have made the windows limited,
mainly because of the problems that clones of them cause in a
multi-tasking program. But, in general, I tend to be on the side of
"provide maximum capability with all reusable object types". Which means
non-limited.

...
>> Sweeping statements about programming style are not likely to be
>> helpful. I tend to feel about finalization like Matt apparently does
>> about access discriminants, but the only time I would say something
like
>> "No serious Ada program can be written without them." is when I'm
>> looking for fight. Even though I believe that is true, I'm well aware
>> that there are many, many Ada projects which have an irrational fear
of
>> finalization, and to characterize them as not being "serious" is not
>> likely to make any friends.
>
>Perhaps it was my use of the word "serious" that was confusing.  I
>should have said "essential," with the same sense that Fred Brooks
>used in his famous paper "Essence and Accidents in Software
>Engineering."
>
>http://atheism.about.com/library/glossary/general/bldef_essence.htm
>
>C++ doesn't require you to use classes, but if you don't, it would be
>a stretch to say that you're programming in "C++."  Really, you're
>using a C++ compiler to compile a C program.  This is not necessarily
>a bad thing -- after all, C++ gives you better compile-time error
>checking and type-safe linkage.  But to not use classes you'd be
>losing something "essential" to C++ programming.
>
>The use of access discriminants in Ada95 is exactly analogous.  For
>example, how would you add controlled-ness to a (tagged) type that is
>part of type hierarchy that isn't already controlled?  The only way I
>know is to do this:
>
>   type NT is new T with private;
>   ...
>private
>   type Control_Type (O : access NT) is
>      new Limited_Controlled with null record;
>
>   type NT is new T with record
>      Control : Control_Type (NT'Access);
>      ...
>   end record;
>
>This is an important Ada95 idiom with which every Ada95 needs to be
>thoroughly familiar.  This idiom and others like it is why I
>characterize access discriminants as "essential" (again, "per se" vs.
>"per accidens") to programming in Ada95.

Sigh. This is a lousy example, for the simple reason that there should
be no such hierarchies. If you can afford the space and time overhead of
a tagged type, you can afford the space and time overhead of a
controlled type. So there simply should not be any tagged types that
aren't controlled. Then this whole example comes up.

Secondly, I certainly know of this idiom, but I've never once found a
case where I needed to use it. I suspect this comes from the "O-O is
everything" mentality, where people are trying to use simulate multiple
inheritance in Ada rather than simply solving the problem. Whenever I've
needed to "connect" objects, I've always used access-to-classwide types,
and added any needed operations. Standing on one's head simply makes
tricky, hard-to-maintain code.

My point is O-O is the frosting on the cake, not the meat. It's useful
for some jobs, but when you start trying to make everything look like
it, you get abominations like access parameters and access
discriminants. Especially when you try to copy existing O-O dogma
instead of realizing that Ada 95 let's you do it better.

                   Randy Brukardt.








^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-24 19:11               ` Matthew Heaney
@ 2003-02-24 21:17                 ` Randy Brukardt
  2003-02-25 17:49                   ` Richard Riehle
  0 siblings, 1 reply; 34+ messages in thread
From: Randy Brukardt @ 2003-02-24 21:17 UTC (permalink / raw)


Matthew Heaney wrote in message
<1ec946d1.0302241111.3e816bb@posting.google.com>...
>"Randy Brukardt" <randy@rrsoftware.com> wrote in message
news:<v5d1sfo9ib2df9@corp.supernews.com>...
>> Matthew Heaney wrote in message
>> <1ec946d1.0302201642.66eb93e5@posting.google.com>...
>>
>> >Here we see the reason why we passed an access parameter: it's
because
>> >we're returning an access value that designates one of our own
>> >components.
>>
>>
>> That reason being only that Ada doesn't support 'in out' parameters
on
>> functions. If it did,
>>
>> fuction Persistence_View
>>      (Object : in out T) return Persistence_Class_Access is
>>    begin
>>       return Object.Persistence_View'Access;
>>    end;
>>
>> would work fine, and would be a lot easier to use as well.
>
>No -- this would be the wrong way to implement the multiple views
>idiom.  You really do want to make explicit the fact that the object
>is being aliased.


All tagged objects are aliased. (It's silly that you have to declare
that for object declarations, and it is true otherwise by default, but
that's just a glitch in the standard). So the fact that it's tagged
makes it explicit. You don't need to introduce junk access types in
order to do it. (Yes, both access parameters and access discriminants
introduce new access types.)

...
>Which makes it identical to how you'd say it in Ada95.  So this is not
>really an Ada issue.


Never, ever use an explicit access in Ada95 if you can avoid it. Save
explicit accesses for dynamic allocation.

>> But that's not going to happen, so we're stuck with terrible
workarounds
>> like 'access' parameters.
>
>Access parameters have other uses besides getting around the lack of
>inout mode for function parameters.  For example, operations that
>accept a user-defined type as an access parameter are primitive for
>the type, and hence are inherited in a derivation.  And an access
>parameter means you don't have to say Op (O.all) everywhere.


I realize that's true, but its a pointless distinction. "in out" and
"access" have pretty much the same semantics inside the subprogram.
Avoid explicit access types unless they are really needed. So 'O'
probably won't be a pointer in the first place, and certainly you don't
want to require that it is a pointer.
I'd much rather say:
   Op (O.all)
(especially as it makes it clear that you're doing a dereference and
thus require a non-null pointer) than
   Op (O'Unchecked_Access)
And the latter requires an explicit, junk 'aliased' declaration. (It's
junk because all tagged types are effectively aliased anyway -- you just
have to pass them to an operation to see that.)

>However, we are in agreement that not having inout mode for functions
>is a ridiculous restriction, since functions in Ada95 do modify their
>arguments (the language just doesn't let you *say* that you do).

Wow! We agree on something! :-)

Unfortunately, no one is willing to vote to change this restriction
(although no one seems to have a legitimate reason for keeping it, just
a bunch of FUD). Sigh.

                  Randy.






^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-24 21:05                   ` Randy Brukardt
@ 2003-02-25 14:15                     ` Frank J. Lhota
  2003-02-26  1:05                       ` Randy Brukardt
  0 siblings, 1 reply; 34+ messages in thread
From: Frank J. Lhota @ 2003-02-25 14:15 UTC (permalink / raw)


> My point is O-O is the frosting on the cake, not the meat.

Frosting on a meat cake? UG!





^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-24 21:17                 ` Randy Brukardt
@ 2003-02-25 17:49                   ` Richard Riehle
  0 siblings, 0 replies; 34+ messages in thread
From: Richard Riehle @ 2003-02-25 17:49 UTC (permalink / raw)


Randy Brukardt wrote:

> Never, ever use an explicit access in Ada95 if you can avoid it. Save
> explicit accesses for dynamic allocation.

Except, perhaps, as access to subprograms.  This turns out to be
a powerful capability of Ada 95.

Richard Riehle




^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: "access constant" discriminant
  2003-02-25 14:15                     ` Frank J. Lhota
@ 2003-02-26  1:05                       ` Randy Brukardt
  0 siblings, 0 replies; 34+ messages in thread
From: Randy Brukardt @ 2003-02-26  1:05 UTC (permalink / raw)


Frank J. Lhota wrote in message ...
>> My point is O-O is the frosting on the cake, not the meat.
>
>Frosting on a meat cake? UG!


Sigh. Mixed metaphors. What can I say? Probably that belongs in the
Dilbert Newsletter.

       Randy.




^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2003-02-26  1:05 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-10  8:26 "access constant" discriminant tmoran
2003-02-10 14:43 ` Frank J. Lhota
2003-02-10 18:57   ` tmoran
2003-02-15 19:17     ` Richard Riehle
2003-02-15 19:59       ` Larry Kilgallen
2003-02-15 23:53         ` Richard Riehle
2003-02-16  1:50           ` Eric G. Miller
2003-02-20  2:23         ` Matthew Heaney
2003-02-20 17:34         ` Stephen Leake
2003-02-21  0:42           ` Matthew Heaney
2003-02-21 10:41             ` Lutz Donnerhacke
2003-02-21 20:21               ` Randy Brukardt
2003-02-23 12:22                 ` Simon Wright
2003-02-24  7:06                 ` Dale Stanbrough
2003-02-24 18:58                 ` Matthew Heaney
2003-02-24 21:05                   ` Randy Brukardt
2003-02-25 14:15                     ` Frank J. Lhota
2003-02-26  1:05                       ` Randy Brukardt
2003-02-24 16:03               ` Matthew Heaney
2003-02-21 15:03             ` Hyman Rosen
2003-02-21 20:09               ` Randy Brukardt
2003-02-21 21:33               ` Matthew Heaney
2003-02-21 20:07             ` Randy Brukardt
2003-02-24 19:11               ` Matthew Heaney
2003-02-24 21:17                 ` Randy Brukardt
2003-02-25 17:49                   ` Richard Riehle
2003-02-20  2:23       ` Matthew Heaney
2003-02-20  2:20     ` Matthew Heaney
2003-02-10 19:26 ` Robert A Duff
2003-02-10 22:27 ` Rod Chapman
2003-02-11  2:00   ` Jeffrey Carter
2003-02-20  2:28   ` Matthew Heaney
2003-02-20  9:45     ` Lutz Donnerhacke
2003-02-20  2:17 ` Matthew Heaney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox