comp.lang.ada
 help / color / mirror / Atom feed
* OO in Ada
@ 1998-05-15  0:00 Gisle S{lensminde
  0 siblings, 0 replies; 28+ messages in thread
From: Gisle S{lensminde @ 1998-05-15  0:00 UTC (permalink / raw)



When you are developing programs by Object-oriented methods in say C++, 
you have lots of books describing OO, with examples in that language. 
Even many books are ment to be general OO-books, like Booch and
several others, I miss examples of how you do things in Ada 95.
For example, how do you organize packages vs types. This is not an
issue in C++, because you doesn't have the option. The questions is 
shortly:

1. What is C++ (or Java) things
2. What is 'OO language with class as type' things
3. What is general OO issues.

I haven't found much on adahome.com, and other WWW sites, I have not 
found any advanced OO books which explain Ada 95 OO. I find it difficult 
to apply all the OO programming development teqniques i have learnt when 
using Ada, and that's not because Ada is unsuitable for OO programming.

-- 
------------------------------------------------------------------------
  Gisle S�lensminde                Tlf:   55 34 07 63
  Eliasmarken 16                   
  5031 Laksev�g                    epost: gisle@ii.uib.no   

  UNIX is user friendly. It's just selective about who its friends are.
------------------------------------------------------------------------








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

* OO in Ada
@ 2002-10-04  2:14 Rick Duley
  2002-10-04  2:55 ` Jim Rogers
                   ` (7 more replies)
  0 siblings, 8 replies; 28+ messages in thread
From: Rick Duley @ 2002-10-04  2:14 UTC (permalink / raw)


Hi all

I believe that I am the last surviving academic Ada programmer in Perth, 
Western Australia and I am in need of some help.  I am having problems 
coming to terms with the rationale behind Object Oriented programming in Ada 
and there is no-one I know in Perth to talk to.  I'm hoping you folk won't 
mind giving me a hand.

Perhaps I had better start by explaining my (mis-) understanding of the 
general principle of inheritance.

Suppose I have defined an object Pen to have the form:

+-------------------------------------------+
| Pen                                       |
+-------------------------------------------+
| X     : Integer;                          |
| Y     : Integer;                          |
| Color : Color_Type;                       |
+-------------------------------------------+
| procedure Move_To(This : in out Pen;      |
|                   X    : in     Natural;  |
|                   Y    : in     Natural); |
| -- move the pen to the specified location |
| --  without drawing                       |
|                                           |
| procedure Draw_To(This : in out Pen;      |
|                   X    : in     Natural;  |
|                   Y    : in     Natural); |
| -- draw a line from the current location  |
| --  to (X,Y) using the pen's              |
| --  current color.  the pen's location    |
| --  moves to (X,Y)                        |
|                                           |
| function New_Pen(X     : Natural;         |
|                  Y     : Natural;         |
|                  Color : Color_Type)      |
| return Pen_Access;                        |
| -- returns access to an initialised Pen   |
+-------------------------------------------+

This object should be initialised by New_Pen and all the functionality it 
should need should be supplied by the other two methods.  Of course, if you 
want to change Pen Colour in midstream you would have to provide the 
functionality to do so but let's keep this simple so I can get a handle on 
it ;)

Extension of this class to Thick_Pen should, according to me, result in a 
class having the form:

+-------------------------------------------+
| Thick_Pen                                 |
+-------------------------------------------+
| X         : Integer;                      |
| Y         : Integer;                      |
| Color     : Color_Type;                   |
| Thickness : Positive;                     |
+-------------------------------------------+
| --=== inherited from Pen_Class ===--      |
| procedure Move_To(This : in out Pen;      |
|                   X    : in     Natural;  |
|                   Y    : in     Natural); |
| -- move the pen to the specified location |
| --  without drawing                       |
|                                           |
| procedure Draw_To(This : in out Pen;      |
|                   X    : in     Natural;  |
|                   Y    : in     Natural); |
| -- draw a line from the current location  |
| --  to (X,Y) using the pen's              |
| --  current color.  the pen's location    |
| --  moves to (X,Y)                        |
|                                           |
| function New_Pen(X     : Natural;         |
|                  Y     : Natural;         |
|                  Color : Color_Type)      |
| return Pen_Access;                        |
| -- returns access to an initialised Pen   |
|                                           |
| --=== new in Thick_Pen_Class ===--        |
| procedure Move_To(This : in out Thick_Pen;|
|                   X    : in     Natural;  |
|                   Y    : in     Natural); |
| -- move the pen to the specified location |
| --  without drawing                       |
|                                           |
| procedure Draw_To(This : in out Thick_Pen;|
|                   X    : in Natural;      |
|                   Y    : in Natural);     |
| -- draw a line from the current location  |
| --  to (X,Y) using the pen's              |
| -- current color.  the pen's location     |
| --  moves to (X,Y).  The                  |
| -- vertical thickness of the pen is given |
| --  by Thickness.                         |
|                                           |
| function New_Thick_Pen                    |
|    (X         : Natural;                  |
|     Y         : Natural;                  |
|     Color     : Color_Type;               |
|     Thickness : in Positive)              |
| return Thick_Pen_Access;                  |
| -- returns access to initialised Thick_Pen|
|-------------------------------------------+

I would expect all the class attributes, the data variables, to be accessed 
by the methods of the derived class with the overloading providing the 
polymorphism.  My problems start when this doesn't happen.

1.   All the texts I can find which deal in any degree at all with OO in Ada 
teach that the tagged record in an object declaration should be 'private'.  
When you follow this line, a derived class does not have direct access to 
the object attributes of the base class, i.e. _there_is_no_inheritace_.

2.   To provide the derived class with access to the object attributes of 
the base class I have to create user-defined methods in the base class.  
This has two effects:
     a) the object attributes of the base class are now effectively public, 
i.e. accessible (through the user-defined methods) to any client module 
through 'with' and 'use' -  which effectively negates the act of making them 
private in the first place;
     b) having to provide accessibility in this manner emphasises the fact 
that inheritance did not occur.

3.   If the tagged record in the base class is left public and the derived 
class is in a child package of the package defining the base class, then the 
base class attributes are accessible to the derived class.  So far so good 
:)  However, if in a program 'use'ing the child package of 'Thick_Pen' (and 
not mentioning the base package of 'Pen') I make a call to the routine 
'Draw' with an actual parameter of the type 'Pen' I get a compiler error 
message to the effect that 'Draw' is not visible.  In other words, Thick_Pen 
has not inherited the operation Draw for 'Pen'  Again, 
_there_is_no_inheritace_.

4.  Further along that line, Thick_Pen does not inherit the type Pen so I 
cannot declare a Pen (or Pen_Access) unless I 'with' and 'use' the package 
in which Pen is declared.  This means that making the package in which 
Thick_Pen is declared a child of the package in which Pen is declared 
totally useless.  _There_is_no_inheritance_!

I have to say that this is the first time in pretty near a decade I have 
been writing in and teaching with Ada that Ada hasn't come up with the 
goods.  Do I labour under some serious misunderstanding, do I have something 
terribly wrong?

5.   One final thing (for this time anyway ;), why is it that that Ada does 
not use the intuitive 'object.method' syntax for making calls to and object. 
   This would mean that (in the case described in section 3) the call would 
read

	Pen.Draw(To_X => n, To_Y => n);

and with inheritance this would be accessible through the child package 
declaring Thick_Pen.  While I'm okay with using the existing syntax, I feel 
the 'object.method' syntax is more intuitive and in line with OO thinking.  
If there are people working on Ada0x then maybe we should be putting this 
forward for consideration.


So, you see, I'm all at sea.  Can someone help me out?
Thanks



-------------------------------------------------
Rick Duley
23/209 Walcott St
North Perth, Western Australia 6006
mob: +61 040 910 6049
                                /-_|\
                               /     \
                         perth *_.-._/
                                    v
Experience is the worst of teachers
       It gives you the exam
                before it gives you the lecture


_________________________________________________________________
Join the world�s largest e-mail service with MSN Hotmail. 
http://www.hotmail.com




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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
@ 2002-10-04  2:55 ` Jim Rogers
  2002-10-04 17:35   ` Hyman Rosen
  2002-10-04  3:37 ` Chad R. Meiners
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 28+ messages in thread
From: Jim Rogers @ 2002-10-04  2:55 UTC (permalink / raw)


Rick Duley wrote:

> Hi all
> 
> I believe that I am the last surviving academic Ada programmer in Perth, 
> Western Australia and I am in need of some help.  I am having problems 
> coming to terms with the rationale behind Object Oriented programming in 
> Ada and there is no-one I know in Perth to talk to.  I'm hoping you folk 
> won't mind giving me a hand.
> 
> Perhaps I had better start by explaining my (mis-) understanding of the 
> general principle of inheritance.
> 
> Suppose I have defined an object Pen to have the form:
> 
> +-------------------------------------------+
> | Pen                                       |
> +-------------------------------------------+
> | X     : Integer;                          |
> | Y     : Integer;                          |
> | Color : Color_Type;                       |
> +-------------------------------------------+
> | procedure Move_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- move the pen to the specified location |
> | --  without drawing                       |
> |                                           |
> | procedure Draw_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- draw a line from the current location  |
> | --  to (X,Y) using the pen's              |
> | --  current color.  the pen's location    |
> | --  moves to (X,Y)                        |
> |                                           |
> | function New_Pen(X     : Natural;         |
> |                  Y     : Natural;         |
> |                  Color : Color_Type)      |
> | return Pen_Access;                        |
> | -- returns access to an initialised Pen   |
> +-------------------------------------------+
> 
> This object should be initialised by New_Pen and all the functionality 
> it should need should be supplied by the other two methods.  Of course, 
> if you want to change Pen Colour in midstream you would have to provide 
> the functionality to do so but let's keep this simple so I can get a 
> handle on it ;)
> 
> Extension of this class to Thick_Pen should, according to me, result in 
> a class having the form:
> 
> +-------------------------------------------+
> | Thick_Pen                                 |
> +-------------------------------------------+
> | X         : Integer;                      |
> | Y         : Integer;                      |
> | Color     : Color_Type;                   |
> | Thickness : Positive;                     |
> +-------------------------------------------+
> | --=== inherited from Pen_Class ===--      |
> | procedure Move_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- move the pen to the specified location |
> | --  without drawing                       |
> |                                           |
> | procedure Draw_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- draw a line from the current location  |
> | --  to (X,Y) using the pen's              |
> | --  current color.  the pen's location    |
> | --  moves to (X,Y)                        |
> |                                           |
> | function New_Pen(X     : Natural;         |
> |                  Y     : Natural;         |
> |                  Color : Color_Type)      |
> | return Pen_Access;                        |
> | -- returns access to an initialised Pen   |
> |                                           |
> | --=== new in Thick_Pen_Class ===--        |
> | procedure Move_To(This : in out Thick_Pen;|
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- move the pen to the specified location |
> | --  without drawing                       |
> |                                           |
> | procedure Draw_To(This : in out Thick_Pen;|
> |                   X    : in Natural;      |
> |                   Y    : in Natural);     |
> | -- draw a line from the current location  |
> | --  to (X,Y) using the pen's              |
> | -- current color.  the pen's location     |
> | --  moves to (X,Y).  The                  |
> | -- vertical thickness of the pen is given |
> | --  by Thickness.                         |
> |                                           |
> | function New_Thick_Pen                    |
> |    (X         : Natural;                  |
> |     Y         : Natural;                  |
> |     Color     : Color_Type;               |
> |     Thickness : in Positive)              |
> | return Thick_Pen_Access;                  |
> | -- returns access to initialised Thick_Pen|
> |-------------------------------------------+
> 
> I would expect all the class attributes, the data variables, to be 
> accessed by the methods of the derived class with the overloading 
> providing the polymorphism.  My problems start when this doesn't happen.
> 
> 1.   All the texts I can find which deal in any degree at all with OO in 
> Ada teach that the tagged record in an object declaration should be 
> 'private'.  When you follow this line, a derived class does not have 
> direct access to the object attributes of the base class, i.e. 
> _there_is_no_inheritace_.


If you want direct access to the private members of a tagged type you
must create that tagged type in a child package.


> 
> 2.   To provide the derived class with access to the object attributes 
> of the base class I have to create user-defined methods in the base 
> class.  This has two effects:
>     a) the object attributes of the base class are now effectively 
> public, i.e. accessible (through the user-defined methods) to any client 
> module through 'with' and 'use' -  which effectively negates the act of 
> making them private in the first place;
>     b) having to provide accessibility in this manner emphasises the 
> fact that inheritance did not occur.
> 


This approach is commonly taught for Java, but not always viewed as
a *good thing*. It does allow you to provide subprograms that enforce
state rules about the data that cannot be enforced with simple public
access. The problem is that most people do not enforce state in these
subprograms, resulting in the effect you describe in (a) above.


> 3.   If the tagged record in the base class is left public and the 
> derived class is in a child package of the package defining the base 
> class, then the base class attributes are accessible to the derived 
> class.  So far so good :)  However, if in a program 'use'ing the child 
> package of 'Thick_Pen' (and not mentioning the base package of 'Pen') I 
> make a call to the routine 'Draw' with an actual parameter of the type 
> 'Pen' I get a compiler error message to the effect that 'Draw' is not 
> visible.  In other words, Thick_Pen has not inherited the operation Draw 
> for 'Pen'  Again, _there_is_no_inheritace_.



Just how are you defining your derived class? It should be defined as
something like:

    type Thick_Pen is new Pen with private;

    ....


private
    type Thick_Pen is new Pen with record
      Thickness : Positive;
    end record;


> 
> 4.  Further along that line, Thick_Pen does not inherit the type Pen so 
> I cannot declare a Pen (or Pen_Access) unless I 'with' and 'use' the 
> package in which Pen is declared.  This means that making the package in 
> which Thick_Pen is declared a child of the package in which Pen is 
> declared totally useless.  _There_is_no_inheritance_!
> 
> I have to say that this is the first time in pretty near a decade I have 
> been writing in and teaching with Ada that Ada hasn't come up with the 
> goods.  Do I labour under some serious misunderstanding, do I have 
> something terribly wrong?


It would really help if you showed your offending Ada code. I still
suspect you are not extending your tagged type correctly. Until you
do that you will not get inheritance.


> 
> 5.   One final thing (for this time anyway ;), why is it that that Ada 
> does not use the intuitive 'object.method' syntax for making calls to 
> and object.   This would mean that (in the case described in section 3) 
> the call would read
> 
>     Pen.Draw(To_X => n, To_Y => n);


Not quite. Pen is the name of the tagged type. It would look more like:

   My_Pen : Pen;

   My_Pen.Draw(To_X => n, To_Y => n);

There are several reasons why this form was not done in Ada. In C++ this
syntax is good for virtual functions but illegal for static functions. This
causes nasty problems in C++ template construction. C++ (and Java) forbid
dispatching based upon the return type of a function. This is one of the
side effects of the 'object.method' notation.

Ada avoids all these problems with its notation. Recent discussions about
future version of C++ have strongly suggested that the 'object.method'
notation has a low return on investment and should be phased out by allowing
virtual functions to be called in the same way as static functions.


> 
> and with inheritance this would be accessible through the child package 
> declaring Thick_Pen.  While I'm okay with using the existing syntax, I 
> feel the 'object.method' syntax is more intuitive and in line with OO 
> thinking.  If there are people working on Ada0x then maybe we should be 
> putting this forward for consideration.
> 
> 
Jim Rogers




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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
  2002-10-04  2:55 ` Jim Rogers
@ 2002-10-04  3:37 ` Chad R. Meiners
  2002-10-04  5:32 ` Simon Wright
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 28+ messages in thread
From: Chad R. Meiners @ 2002-10-04  3:37 UTC (permalink / raw)



"Rick Duley" <rickduley@hotmail.com> wrote in message
news:mailman.1033697703.29112.comp.lang.ada@ada.eu.org...
> Hi all
>> and there is no-one I know in Perth to talk to.  I'm hoping you folk
won't
> mind giving me a hand.

Always willing to help an academic in need ;)

I believe the following chunk of code is a proper method of representing the
pens in an OO manner.  Let me know if this doesn't address your concerns.

package Pens is

   type Colors is (Red, Green, Blue);

   type Pen is tagged private;

   procedure Move (Item : in out Pen; To_X : Natural; To_Y : Natural);

   procedure Draw (Item : in out Pen; To_X : Natural; To_Y : Natural);

   package Builder is
      -- The builder is not a primitive of Pen'class
      function New_Pen (Color : Colors; X : Natural; Y : Natural) return
Pen;

   end Builder;

private

   type Pen is tagged record
      Color : Colors;
      X     : Natural;
      Y     : Natural;
   end record;

end Pens;

package Pens.Thick is

   type Thick_Pen is new Pen with private;
   -- This type and its procedures and function have full access to
   -- Pen's representation.

   procedure Draw (Item : in out Thick_Pen; To_X : Natural; To_Y : Natural);

   package Builder is

      function New_Thick_Pen (Color     : Colors;
                              X         : Natural;
                              Y         : Natural;
                              Thickness : Positive )
                             return Thick_Pen;

   end Builder;

private

   type Thick_Pen is new Pen with record
      Thickness : Positive;
   end record;

end Pens.Thick;

with Pens.Thick;

use  Pens, Pens.Builder, Pens.Thick, Pens.Thick.Builder;

procedure Test_Pens is

   procedure Draw_Box (Item : in out Pen'Class; X1 : Natural; Y1 : Natural;
                                                X2 : Natural; Y2 : Natural)
is

      -- Example of dispatching.

   begin
      Move (Item, X1, Y1);

      Draw (Item, X2, Y1);
      Draw (Item, X2, Y2);
      Draw (Item, X1, Y2);
      Draw (Item, X1, Y1);
   end Draw_Box;

   Green_Pen  : Pens.Pen := New_Pen (Green, 3, 4);
   Red_Pen    : Pens.Thick.Thick_Pen := New_Thick_Pen(Red, 3, 4, 1);

begin

   Draw_Box (Green_Pen, 0, 0, 50, 50);
   Draw_Box (Red_Pen, 10, 10, 30, 30);

end Test_Pens;

> 1.   All the texts I can find which deal in any degree at all with OO in
Ada
> teach that the tagged record in an object declaration should be 'private'.
> When you follow this line, a derived class does not have direct access to
> the object attributes of the base class, i.e. _there_is_no_inheritace_.

If you need access to a base classes representation, create the derived
class in a child package.

> 3.   If the tagged record in the base class is left public and the derived
> class is in a child package of the package defining the base class, then
the
> base class attributes are accessible to the derived class.  So far so good
> :)  However, if in a program 'use'ing the child package of 'Thick_Pen'
(and
> not mentioning the base package of 'Pen') I make a call to the routine
> 'Draw' with an actual parameter of the type 'Pen' I get a compiler error
> message to the effect that 'Draw' is not visible.  In other words,
Thick_Pen
> has not inherited the operation Draw for 'Pen'  Again,
> _there_is_no_inheritace_.

Please post a code example with the compiler error with these types of
questions.  It will help us help you.

> I have to say that this is the first time in pretty near a decade I have
> been writing in and teaching with Ada that Ada hasn't come up with the
> goods.  Do I labour under some serious misunderstanding, do I have
something
> terribly wrong?

hmm... Well Ada's method of OOP takes a little time to get use to, but it
sounds like you have some misunderstandings of the OO system.

> 5.   One final thing (for this time anyway ;), why is it that that Ada
does
> not use the intuitive 'object.method' syntax for making calls to and
object.
>    This would mean that (in the case described in section 3) the call
would
> read
>
> Pen.Draw(To_X => n, To_Y => n);
>
> and with inheritance this would be accessible through the child package
> declaring Thick_Pen.  While I'm okay with using the existing syntax, I
feel
> the 'object.method' syntax is more intuitive and in line with OO thinking.
> If there are people working on Ada0x then maybe we should be putting this
> forward for consideration.

The object.method syntax is inconsistent with the rest of Ada's procedure
and function syntax.  I don't think the 'object.method' syntax is more
intuitive since I have seen too many TA's try to 'help' struggling students
by saying "OOP is when you use the 'object.method' syntax" ;)  I prefer
Ada's method of OOP although I don't use it much.

-CRM





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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
  2002-10-04  2:55 ` Jim Rogers
  2002-10-04  3:37 ` Chad R. Meiners
@ 2002-10-04  5:32 ` Simon Wright
  2002-10-04  6:01 ` tmoran
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 28+ messages in thread
From: Simon Wright @ 2002-10-04  5:32 UTC (permalink / raw)


If it wouldnt be cheating, you could check out John English's book
http://www.it.bton.ac.uk/staff/je/adacraft/

-- 
Simon Wright                       Work Email: simon.j.wright@amsjv.com
AMS                                           Voice: +44(0)23-9270-1778
Integrated Systems Division                     FAX: +44(0)23-9270-1800



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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
                   ` (2 preceding siblings ...)
  2002-10-04  5:32 ` Simon Wright
@ 2002-10-04  6:01 ` tmoran
  2002-10-04 15:05 ` Matthew Heaney
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 28+ messages in thread
From: tmoran @ 2002-10-04  6:01 UTC (permalink / raw)


>Extension of this class to Thick_Pen should, according to me, result in a
>class having the form:
>
>+-------------------------------------------+
>| Thick_Pen                                 |
>+-------------------------------------------+
>| X         : Integer;                      |
>| Y         : Integer;                      |
>| Color     : Color_Type;                   |
>| Thickness : Positive;                     |
>+-------------------------------------------+
  No.  A Thick_Pen is a Pen with a thickness.
    type Thick_Pen is new Pen with record
      Thickness : Positive;
    end record;
The original Pen may (does, in this case) have an X,Y (or perhaps
R,Theta) and Color, and perhaps also a Window_Handle and who knows what
else, but those details are not a concern of Thick_Pen.
  If code for a Thick_Pen really does need to get at the internal,
private, record components such as X or Y, then Thick_Pen will have to
be declared in a child of the package that declares Pen.  If you have
good abstraction and separation of concerns, that shouldn't be necessary.

>| --=== inherited from Pen_Class ===--      |
>| procedure Move_To(This : in out Pen;      |
>|                   X    : in     Natural;  |
>|                   Y    : in     Natural); |
>| -- move the pen to the specified location |
>| --  without drawing                       |
  No.  What's inherited is a compiler-created
   procedure Move_To(This : in out Thick_Pen;
                     X    : in     Natural;
                     Y    : in     Natural);
unless of course you specifically override that with your own
brand new Move(Thick_Pen).  Usually in that case you would have something
like:
   procedure Move_To(This : in out Thick_Pen;
                     X    : in     Natural;
                     Y    : in     Natural) is
   begin
     -- do something special for Thick_Pens that isn't done for Pens
     Move_To(Pen(This), X,Y);  -- move the underlying Pen
   end Move_To;

>|                                           |
>| function New_Pen(X     : Natural;         |
>|                  Y     : Natural;         |
>|                  Color : Color_Type)      |
>| return Pen_Access;                        |
>| -- returns access to an initialised Pen   |
  This function can't be inherited, since it could only initialize
a Pen, but wouldn't know what to do about the extra attributes of a
new Thick_Pen.  So you will *have to* write your own
   function New_Pen(X     : Natural;
                    Y     : Natural;
                    Color : Color_Type)
   return Thick_Pen_Access;
Here you start to get in trouble since you have no way to initialize
a Pen's parts except by getting a pointer to a Pen.  It would have
been much simpler if New_Pen returned a Pen or a Thick_Pen rather
than an access to one.  Of course you would still need a specifically
written "New_Pen(...) return Thick_Pen", since you can't inherit
New_Pen(...) return Pen since it doesn't know enough.  This New_Pen
function, since it doesn't have a Thickness parameter, will have to
return a Thick_Pen with some default value for Thickness.

>| function New_Thick_Pen                    |
>|    (X         : Natural;                  |
>|     Y         : Natural;                  |
>|     Color     : Color_Type;               |
>|     Thickness : in Positive)              |
>| return Thick_Pen_Access;                  |
>| -- returns access to initialised Thick_Pen|
  This is indeed a brand new function to create new Thick_Pens with
non-default values of Thickness.

> 1.   All the texts I can find which deal in any degree at all with OO in Ada
> teach that the tagged record in an object declaration should be 'private'.
> When you follow this line, a derived class does not have direct access to
> the object attributes of the base class, i.e. _there_is_no_inheritace_.
  The attributes should normally be private because nobody has a Need To
Know about them.  A drawing program shouldn't need to know about the
attributes of a Pen - just how to use one.  Code to Move and Draw and
whatever with a Thick_Pen shouldn't need to know either - just that
there exists a Pen object that you can create, move, and draw.  If
Thick_Pen, or the drawing program, need to know things like the Color,
or position, there should be functions
  function Color_Of(This : Pen) return Color;
  function Position_Of(This : Pen) return Position_Type;
Those functions will also be inherited by Thick_Pen, presuming there's
no special handling required to find a Thick_Pen's color or position.
If some special stuff *is* needed for a Thick_Pen, an adjustment
to Position based on Thickness, say, then you'll write a new
  function Position_Of(This : Thick_Pen) return Position_Type;
to override the inherited one.

>:)  However, if in a program 'use'ing the child package of 'Thick_Pen' (and
>not mentioning the base package of 'Pen') I make a call to the routine
>'Draw' with an actual parameter of the type 'Pen' I get a compiler error
>message to the effect that 'Draw' is not visible.  In other words, Thick_Pen
>has not inherited the operation Draw for 'Pen'
  Wrong.  There is an inherited Draw - it takes a parameter of type
Thick_Pen.  If you want to call a different Draw, one that takes a parameter
of type Pen, then you'll need to give a full name or have a Use clause
for the package containing *that* Draw.

> 4.  Further along that line, Thick_Pen does not inherit the type Pen so I
  Your package that declares Thick_Pen, declares Thick_Pen, not Pen.
It must 'with' Pen_Package of course in order to be able to say "is new Pen",
and that 'with' brings along function Move(This : Pen), etc.  The
"is new Pen" creates brand new functions Move(This : Thick_Pen) etc.  If
you don't override those brand new functions, the compiler will implement
them as calls to Move(This : Pen) etc.

package Pen_Package is
  type Pen is tagged private;
  procedure Move_To(This : in out Pen;
                    X    : in     Natural;
                    Y    : in     Natural);
  -- Draw, New_Pen, and everything else any outsiders need know
private
  type Pen is tagged record
    R,Theta : Float := 0.0;  -- just to be weird
    Color : Colors:= Red;
    Handle : Windows.Handles := Windows.Null_Handle;
    -- and anything else as appropriate
  end record;
end Pen_Package;

with Pen_Package;
package Thick_Pen_Package is

  type Thick_Pen is Pen_Package.Pen with private;

  Out_Of_Ink : Exception;

  procedure Draw_To(This : in out Thick_Pen;
                    X    : in     Natural;
                    Y    : in     Natural);
    -- every Draw operation uses ink, amount depending on thickness of pen
    -- raises Out_Of_Ink if it runs out of ink.

  -- by inheritance from Pen:
  -- procedure Move_To(This : in out Thick_Pen;
  --                   X    : in     Natural;
  --                   Y    : in     Natural);

private
  type Thick_Pen is Pen_Package.Pen with record
    Thickness : Positive := 0;
    Remaining_Ink : Positive := 100;
  end record;
end Thick_Pen;

package body Thick_Pen_Package is
  procedure Draw_To(This : in out Pen;
                    X    : in     Natural;
                    Y    : in     Natural) is
  begin
    if This.Remaining_Ink = 1 then raise Out_Of_Ink;end if;
    Remaining_Ink := Remaining_Ink - Thickness;
    Pen_Package.Draw_To(Pen_Package.Pen(This), X, Y);
  end Draw_To;
end Thick_Pen_Package;
  ...
  T : Thick_Pen;
  ...
  Move_To(T, 10,10);  -- uses compiler created, ie, inherited, Move_Pen
  Draw_To(T, 20,20);  -- use explicitly created Draw_To

> not use the intuitive 'object.method' syntax for making calls to and object.
  Because some of us find it not at all intuitive? ;)
In addition to advantages mentioned by others, Ada lets you have multiple
tagged type parameters, which is much nicer when no one parameter is
special:
  type Object is tagged record
    X,Y : Float;
  end record;
  function Distance(A,B : Object) return Float;
  ...
  if Distance(Car, Truck) < 1.0 then ...
vs
  if Car.Distance(Truck) < 1.0 then ...



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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
                   ` (3 preceding siblings ...)
  2002-10-04  6:01 ` tmoran
@ 2002-10-04 15:05 ` Matthew Heaney
  2002-10-05  2:14 ` SteveD
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 28+ messages in thread
From: Matthew Heaney @ 2002-10-04 15:05 UTC (permalink / raw)



"Rick Duley" <rickduley@hotmail.com> wrote in message
news:mailman.1033697703.29112.comp.lang.ada@ada.eu.org...
>
> Suppose I have defined an object Pen to have the form:
>
> +-------------------------------------------+
> | Pen                                       |
> +-------------------------------------------+
> | X     : Integer;                          |
> | Y     : Integer;                          |
> | Color : Color_Type;                       |
> +-------------------------------------------+
> | procedure Move_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- move the pen to the specified location |
> | --  without drawing                       |
> |                                           |
> | procedure Draw_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- draw a line from the current location  |
> | --  to (X,Y) using the pen's              |
> | --  current color.  the pen's location    |
> | --  moves to (X,Y)                        |
> |                                           |
> | function New_Pen(X     : Natural;         |
> |                  Y     : Natural;         |
> |                  Color : Color_Type)      |
> | return Pen_Access;                        |
> | -- returns access to an initialised Pen   |
> +-------------------------------------------+

I'm not sure why you're using a factory function to return a pointer to a
pen object, but in case that's really what you wanted then you'd have
something like:

package Pens is

   type Pen_Type (<>) is tagged limited private;

   type Pen_Access is access all Pen_Type;

   function New_Pen (X, Y : Natural; C : Color_Type) return Pen_Access;

   procedure Move_To
     (Pen : in out Pen_Type;
      X, Y : Natural);

private

   type Pen_Type is tagged limited record
      X, Y : Integer;
      C : Color_Type;
   end record;

end Pens;



> Extension of this class to Thick_Pen should, according to me, result in a
> class having the form:
>
> +-------------------------------------------+
> | Thick_Pen                                 |
> +-------------------------------------------+
> | X         : Integer;                      |
> | Y         : Integer;                      |
> | Color     : Color_Type;                   |
> | Thickness : Positive;                     |
> +-------------------------------------------+
> | --=== inherited from Pen_Class ===--      |
> | procedure Move_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- move the pen to the specified location |
> | --  without drawing                       |
> |                                           |
> | procedure Draw_To(This : in out Pen;      |
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- draw a line from the current location  |
> | --  to (X,Y) using the pen's              |
> | --  current color.  the pen's location    |
> | --  moves to (X,Y)                        |
> |                                           |
> | function New_Pen(X     : Natural;         |
> |                  Y     : Natural;         |
> |                  Color : Color_Type)      |
> | return Pen_Access;                        |
> | -- returns access to an initialised Pen   |
> |                                           |
> | --=== new in Thick_Pen_Class ===--        |
> | procedure Move_To(This : in out Thick_Pen;|
> |                   X    : in     Natural;  |
> |                   Y    : in     Natural); |
> | -- move the pen to the specified location |
> | --  without drawing                       |
> |                                           |
> | procedure Draw_To(This : in out Thick_Pen;|
> |                   X    : in Natural;      |
> |                   Y    : in Natural);     |
> | -- draw a line from the current location  |
> | --  to (X,Y) using the pen's              |
> | -- current color.  the pen's location     |
> | --  moves to (X,Y).  The                  |
> | -- vertical thickness of the pen is given |
> | --  by Thickness.                         |
> |                                           |
> | function New_Thick_Pen                    |
> |    (X         : Natural;                  |
> |     Y         : Natural;                  |
> |     Color     : Color_Type;               |
> |     Thickness : in Positive)              |
> | return Thick_Pen_Access;                  |
> | -- returns access to initialised Thick_Pen|
> |-------------------------------------------+

In general, the tagged types in a class should be declared in a hierachy of
packages:

package Pens.Thick is

   type Pen_Type is new Pens.Pen_Type with private;

   type Pen_Access is access Pen_Type;

   function New_Pen
     (X, Y : Natural;
      C : Color_Type;
      T : Positive) return Pen_Access;

   procedure Move_To
     (Pen : in out Pen_Type;
      X, Y : Natural);

private

   type Pen_Type is new Pens.Pen_Type with record
      Thickness : Positive;
   end record;

end Pens.Thick;



> 1.   All the texts I can find which deal in any degree at all with OO in
Ada
> teach that the tagged record in an object declaration should be 'private'.
> When you follow this line, a derived class does not have direct access to
> the object attributes of the base class, i.e. _there_is_no_inheritace_.

Visibility in Ada is determined by the relationship of modules, not types.
If you want a derived type to have visibility to the parent from which it is
derived, then you need to declare the derived type in a child package.
(Note that sometimes you don't want to declare the type in a child package,
but this is not one of those times.)

> 2.   To provide the derived class with access to the object attributes of
> the base class I have to create user-defined methods in the base class.

No.  Because the type is declared in a child package, then it has visibility
to the private part of the parent package.

> I have to say that this is the first time in pretty near a decade I have
> been writing in and teaching with Ada that Ada hasn't come up with the
> goods.  Do I labour under some serious misunderstanding, do I have
something
> terribly wrong?

Indeed, you do labour.  All you need to do is declare Thick_Pen in a child
package.

> 5.   One final thing (for this time anyway ;), why is it that that Ada
does
> not use the intuitive 'object.method' syntax for making calls to and
object.
>    This would mean that (in the case described in section 3) the call
would
> read
>
> Pen.Draw(To_X => n, To_Y => n);
>
> and with inheritance this would be accessible through the child package
> declaring Thick_Pen.  While I'm okay with using the existing syntax, I
feel
> the 'object.method' syntax is more intuitive and in line with OO thinking.
> If there are people working on Ada0x then maybe we should be putting this
> forward for consideration.

In C++, I can do this:

class C { ... };
bool operator=(const C& lhs, const C& rhs);

Why doesn't C++ use the "intuitive syntax"?








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

* Re: OO in Ada
  2002-10-04  2:55 ` Jim Rogers
@ 2002-10-04 17:35   ` Hyman Rosen
  2002-10-05  0:20     ` Jim Rogers
  0 siblings, 1 reply; 28+ messages in thread
From: Hyman Rosen @ 2002-10-04 17:35 UTC (permalink / raw)


Jim Rogers wrote:
 > In C++ this syntax is good for virtual functions
 > but illegal for static functions. This causes nasty
 > problems in C++ template construction.

You don't mean 'virtual' and 'static', you mean
'member function' and 'non-member function'. It's
not so much an issue of nasty problems. It's just
that having two different notations for calling a
method means that when you're writing a template
you have to know which notation to use, which
limits its genericity.

 > C++ (and Java) forbid dispatching based upon the
 > return type of a function. This is one of the
> side effects of the 'object.method' notation.

Your first statement is true, but your second is
false. Why do you think object.method would prevent
dispatching on return type?

> should be phased out by allowing [member] functions
 > to be called in the same way as [non-member] functions.

It will never be phased out, of course, since that would
destroy millions of lines of code. Someone might come up
with a reasonable proposal for allowing the method(object)
notation, though. The problem is the impact this owuld have
on overloading and name lookup, which is already extremely
complicated.

The design issue for C++ is that sometimes you want member
functions as part of an interface and sometimes you want
standalone functions. Having a different calling notation
makes it harder to switch the function from one type to the
other, because you have to modify all the callers.

On the other hand, Ada gives the illusion of multiple dispatch
by allowing several parameters to control dispatching, but then
forcing them all, at runtime, to have the same dynamic type. I
suppose some future version of Ada could lift this restriction
while keeping the same notation, which is good.





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

* Re: OO in Ada
  2002-10-04 17:35   ` Hyman Rosen
@ 2002-10-05  0:20     ` Jim Rogers
  2002-10-05 23:38       ` Dmitry A.Kazakov
  2002-10-06  2:18       ` Hyman Rosen
  0 siblings, 2 replies; 28+ messages in thread
From: Jim Rogers @ 2002-10-05  0:20 UTC (permalink / raw)


Hyman Rosen wrote:

> Jim Rogers wrote:
>  > In C++ this syntax is good for virtual functions
>  > but illegal for static functions. This causes nasty
>  > problems in C++ template construction.
> 
> You don't mean 'virtual' and 'static', you mean
> 'member function' and 'non-member function'. It's
> not so much an issue of nasty problems. It's just
> that having two different notations for calling a
> method means that when you're writing a template
> you have to know which notation to use, which
> limits its genericity.


Thank you. That is just what I wanted to say if I
knew C++ better. Sorry about the error.


> 
>  > C++ (and Java) forbid dispatching based upon the
>  > return type of a function. This is one of the
> 
>> side effects of the 'object.method' notation.
> 
> 
> Your first statement is true, but your second is
> false. Why do you think object.method would prevent
> dispatching on return type?
> 


I think that because the dispatching is always performed on the
type of "object" in object.method. This rule would have to be
seriously modified to dispatch on the return type of a function
(or method in Java's terminology).


>> should be phased out by allowing [member] functions
> 
>  > to be called in the same way as [non-member] functions.
> 
> It will never be phased out, of course, since that would
> destroy millions of lines of code. Someone might come up
> with a reasonable proposal for allowing the method(object)
> notation, though. The problem is the impact this owuld have
> on overloading and name lookup, which is already extremely
> complicated.
> 
> The design issue for C++ is that sometimes you want member
> functions as part of an interface and sometimes you want
> standalone functions. Having a different calling notation
> makes it harder to switch the function from one type to the
> other, because you have to modify all the callers.
> 
> On the other hand, Ada gives the illusion of multiple dispatch
> by allowing several parameters to control dispatching, but then
> forcing them all, at runtime, to have the same dynamic type. I
> suppose some future version of Ada could lift this restriction
> while keeping the same notation, which is good.
> 
> 


I disagree here. Ada does not give the illusion of multiple dispatch.
An Ada subprogram can only be primitive to one type. That characteristic
is determined by the place in the source code where the subprogram
interface is defined. I am not really happy with this design feature,
but it is what it is.

Jim Rogers







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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
                   ` (4 preceding siblings ...)
  2002-10-04 15:05 ` Matthew Heaney
@ 2002-10-05  2:14 ` SteveD
  2002-10-05  8:54   ` Preben Randhol
  2002-10-07 14:10   ` Matthew Heaney
  2002-10-08  9:53 ` John McCabe
  2002-10-08 10:21 ` Preben Randhol
  7 siblings, 2 replies; 28+ messages in thread
From: SteveD @ 2002-10-05  2:14 UTC (permalink / raw)


"Rick Duley" <rickduley@hotmail.com> wrote in message
news:mailman.1033697703.29112.comp.lang.ada@ada.eu.org...
[snip]
> 5.   One final thing (for this time anyway ;), why is it that that Ada
does
> not use the intuitive 'object.method' syntax for making calls to and
object.
>    This would mean that (in the case described in section 3) the call
would
> read
>
> Pen.Draw(To_X => n, To_Y => n);
>
> and with inheritance this would be accessible through the child package
> declaring Thick_Pen.  While I'm okay with using the existing syntax, I
feel
> the 'object.method' syntax is more intuitive and in line with OO thinking.

Although I hear the claim that object.method is more intuitive, I would have
to say I disagree.  In my opinion the only reason you see it as more
intuitive is because you learned it that way first (in a different
programming language).

In C++ there is a hidden "this" pointer quietly hiding in the background
that you must be very much aware of (if you're doing any serious
programming).  In Ada this is an explicit variable passed into the
procedure.  I would guess that a newbie would find the Ada syntax more
intuitive (I haven't heard of any evidence either way).

SteveD





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

* Re: OO in Ada
  2002-10-05  2:14 ` SteveD
@ 2002-10-05  8:54   ` Preben Randhol
  2002-10-07 14:10   ` Matthew Heaney
  1 sibling, 0 replies; 28+ messages in thread
From: Preben Randhol @ 2002-10-05  8:54 UTC (permalink / raw)


On Sat, 05 Oct 2002 02:14:01 GMT, SteveD wrote:

> Although I hear the claim that object.method is more intuitive, I would have
> to say I disagree.  In my opinion the only reason you see it as more
> intuitive is because you learned it that way first (in a different
> programming language).

I agree.

Preben
-- 
Ada95 is good for you.
http://libre.act-europe.fr/Software_Matters/02-C_pitfalls.pdf



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

* Re: OO in Ada
  2002-10-05 23:38       ` Dmitry A.Kazakov
@ 2002-10-05 15:25         ` Jim Rogers
  2002-10-06 21:37           ` Dmitry A.Kazakov
  0 siblings, 1 reply; 28+ messages in thread
From: Jim Rogers @ 2002-10-05 15:25 UTC (permalink / raw)


Dmitry A.Kazakov wrote:

> Jim Rogers wrote:
> 
> 
>>I disagree here. Ada does not give the illusion of multiple dispatch.
>>
> 
> Would "limited multiple dispatch" sound better?
> 
> 
>>An Ada subprogram can only be primitive to one type. That characteristic
>>is determined by the place in the source code where the subprogram
>>interface is defined.
>>
> 
> This is wrong. Technically you could do it, because type declaration areas 
> [before freezing point] may overlap:


I must again diagree. You are wrong. Section 3.9 paragraph 12 of the Ada
Reference Manual states:

"A given subprogram shall not be a dispatching operation of two or more distinct 
tagged types."



> 
> type A is tagged ...
> type B is tagged ...
> procedure Multiple_Dispatch (X : A; Y : B); -- Alas, compilation error


There is a compilation error. Look at what it says. Gnat 3.14p states
"operation can be dispatching in only one type."

This does not provide any for of multiple dispatch, limited or otherwise.





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

* Re: OO in Ada
  2002-10-05  0:20     ` Jim Rogers
@ 2002-10-05 23:38       ` Dmitry A.Kazakov
  2002-10-05 15:25         ` Jim Rogers
  2002-10-06  2:18       ` Hyman Rosen
  1 sibling, 1 reply; 28+ messages in thread
From: Dmitry A.Kazakov @ 2002-10-05 23:38 UTC (permalink / raw)


Jim Rogers wrote:

> I disagree here. Ada does not give the illusion of multiple dispatch.

Would "limited multiple dispatch" sound better?

> An Ada subprogram can only be primitive to one type. That characteristic
> is determined by the place in the source code where the subprogram
> interface is defined.

This is wrong. Technically you could do it, because type declaration areas 
[before freezing point] may overlap:

type A is tagged ...
type B is tagged ...
procedure Multiple_Dispatch (X : A; Y : B); -- Alas, compilation error

>I am not really happy with this design feature, but it is what it is.

Of course limited multiple dispatch is better than nothing, like in C++. 
But both lead to surprises when one need to implement dyadic operations etc.

-- 
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



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

* Re: OO in Ada
  2002-10-05  0:20     ` Jim Rogers
  2002-10-05 23:38       ` Dmitry A.Kazakov
@ 2002-10-06  2:18       ` Hyman Rosen
  2002-10-06  3:00         ` Jim Rogers
  1 sibling, 1 reply; 28+ messages in thread
From: Hyman Rosen @ 2002-10-06  2:18 UTC (permalink / raw)


Jim Rogers wrote:
> I think that because the dispatching is always performed on the
> type of "object" in object.method.

Oh, I'm thinking of overloading on return type, sorry.
There's no such thing as dispatching on return type, since
by definition dispatching requires an object to dispatch
upon!

> I disagree here. Ada does not give the illusion of multiple dispatch.
> An Ada subprogram can only be primitive to one type.

Yes, but that subprogram can take multiple parameters of that type,
and when a call is made to that subprogram with arguments which are
classwide, they must all have the same dynamic type (which is then
used in the dispatch) or an exception results.

I think. I'm not an Ada programmer, after all.




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

* Re: OO in Ada
  2002-10-06  2:18       ` Hyman Rosen
@ 2002-10-06  3:00         ` Jim Rogers
  2002-10-08 21:08           ` Gisle Sælensminde
  0 siblings, 1 reply; 28+ messages in thread
From: Jim Rogers @ 2002-10-06  3:00 UTC (permalink / raw)


Hyman Rosen wrote:

> Jim Rogers wrote:
> 
>> I think that because the dispatching is always performed on the
>> type of "object" in object.method.
> 
> 
> Oh, I'm thinking of overloading on return type, sorry.
> There's no such thing as dispatching on return type, since
> by definition dispatching requires an object to dispatch
> upon!
> 
>> I disagree here. Ada does not give the illusion of multiple dispatch.
>> An Ada subprogram can only be primitive to one type.
> 
> 
> Yes, but that subprogram can take multiple parameters of that type,
> and when a call is made to that subprogram with arguments which are
> classwide, they must all have the same dynamic type (which is then
> used in the dispatch) or an exception results.


You are correct. There is a little more that needs to be said about
this.

Following is a quote from "Ada as a Second Language" 2nd Edition by
Norman Cohen (Section 12.4.4.3)

"At first glance, the requirement that all classwide parameters to a
dispatching call have the same tag may seem overly restrictive. There
are many operations in which it makes sense to manipulate two classwide
variables with different tags. Such an operation should be written as a
classwide subprogram - one with formal parameters explicitly declared to
be of a classwide type - rather than a dispatching program.

For example, the function Earlier_Than was declared in package Transactions
as follows:

    function Earlier_Than
     (Trans1, Trans2 : Transaction_Type'Class) return Boolean;

Because this function has two parameters of type Transaction_Type'Class, it
can be called with one operand that has a tag of Deposit_Type and another that
has the tag of Check_Type. The body of Earlier_Than simply compares the
Date_Part components of its operands, which are present in all
Transaction_Type'Class objects, so this is perfectly sensible. Had the function
been declared as

    function Earlier_Than
      (Trans1, Trans2 : Transaction_Type) return Boolean;

instead, it would have been a dispatching operation. Then a call on
Earlier_Than with two Transaction_Type'Class operands having the tag of
Deposit_Type would have dispatched to the version inherited by Deposit_Type,
and a call with two Transaction_Type'Class operands having the tag of
Check_Type would have dispatched to the (identical) version inherited
by Check_Type, but a call with Transaction_Type'Class operands having
different tags would have raised the exception Constriant_Error. This
would have made Earlier_Than useless for sorting a polymorphic array
of pointers to transactions."

The point being that this still follows the rule that a subprogram can
be primitive to only one type. If you need to call a program with
multiple tags belonging to a classwide hierarchy you must explicitly
create that subprogram, and it will not be a dispatching program.

Since this is not a dispatching subprogram there is no form of multiple
dispatch.

Jim Rogers






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

* Re: OO in Ada
  2002-10-05 15:25         ` Jim Rogers
@ 2002-10-06 21:37           ` Dmitry A.Kazakov
  0 siblings, 0 replies; 28+ messages in thread
From: Dmitry A.Kazakov @ 2002-10-06 21:37 UTC (permalink / raw)


Jim Rogers wrote:

> Dmitry A.Kazakov wrote:
> 
>> Jim Rogers wrote:
>> 
>>>I disagree here. Ada does not give the illusion of multiple dispatch.
>>>
>> Would "limited multiple dispatch" sound better?
>> 
>>>An Ada subprogram can only be primitive to one type. That characteristic
>>>is determined by the place in the source code where the subprogram
>>>interface is defined.
>> 
>> This is wrong. Technically you could do it, because type declaration
>> areas [before freezing point] may overlap:
> 
> I must again diagree. You are wrong. Section 3.9 paragraph 12 of the Ada
> Reference Manual states:
> 
> "A given subprogram shall not be a dispatching operation of two or more
> distinct tagged types."

You missed the point. I didn't challenged this rule. I said that it is 
wrong to think that this rule might be a consequence of the rules 
controlling the place in the source code where a primitive operation is 
allowed to be declared. I showed that this is wrong. For two different 
types there can be a place where one could define a primitive operation for 
any of them:
 
>> type A is tagged ...
>> type B is tagged ...
>> procedure Multiple_Dispatch (X : A; Y : B); -- Alas, compilation error

> There is a compilation error. Look at what it says. Gnat 3.14p states
> "operation can be dispatching in only one type."

Yes, but not because of "a primitive operation is declared too late". 
That's the point.

> This does not provide any for of multiple dispatch, limited or otherwise.

This does not, because it is illegal. But Ada 95 does have multiple 
dispatch, because of:

type A is tagged ...
procedure Multiple_Dispatch (X, Y : A);

This is a case of multiple dispatch because more than one parameter is 
dispatching. It is a limited multiple dispatch because:

1. In the dispatch table [note, table, not a vector like in C++! *] of 
Multiple_Dispatch only diagonal elements can be overridden. Non-diagonal 
elements are final and predefined as raising Constraint_Error.

2. The types associated with the rows and columns of the table have to have 
a common ancestor.

(*) Of course, you can implement this table using a vector.

-- 
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



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

* Re: OO in Ada
  2002-10-05  2:14 ` SteveD
  2002-10-05  8:54   ` Preben Randhol
@ 2002-10-07 14:10   ` Matthew Heaney
  2002-10-07 19:52     ` Jeffrey Carter
  2002-10-08 21:18     ` Dmitry A.Kazakov
  1 sibling, 2 replies; 28+ messages in thread
From: Matthew Heaney @ 2002-10-07 14:10 UTC (permalink / raw)



"SteveD" <nospam_steved94@attbi.com> wrote in message
news:JVrn9.40015$FO4.9224@sccrnsc03...
>
> In C++ there is a hidden "this" pointer quietly hiding in the background
> that you must be very much aware of (if you're doing any serious
> programming).  In Ada this is an explicit variable passed into the
> procedure.

This is also true in Ada, wrt passing unconstrained arrays:

procedure Op (S : String) is

You're actually passing a descriptor on the stack, which contains info about
the string's length and index range.  So here there is "hidden" information
being passed too, not unlike an implicit this-ptr in C++.












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

* Re: OO in Ada
  2002-10-07 14:10   ` Matthew Heaney
@ 2002-10-07 19:52     ` Jeffrey Carter
  2002-10-08 21:18     ` Dmitry A.Kazakov
  1 sibling, 0 replies; 28+ messages in thread
From: Jeffrey Carter @ 2002-10-07 19:52 UTC (permalink / raw)


Matthew Heaney wrote:
> "SteveD" <nospam_steved94@attbi.com> wrote in message
> news:JVrn9.40015$FO4.9224@sccrnsc03...
> 
>>In C++ there is a hidden "this" pointer quietly hiding in the background
>>that you must be very much aware of (if you're doing any serious
>>programming).  In Ada this is an explicit variable passed into the
>>procedure.
> 
> 
> This is also true in Ada, wrt passing unconstrained arrays:
> 
> procedure Op (S : String) is
> 
> You're actually passing a descriptor on the stack, which contains info about
> the string's length and index range.  So here there is "hidden" information
> being passed too, not unlike an implicit this-ptr in C++.

How this is passed is implementation dependent. Some implementations may 
work as indicated, but others may simply pass an address. Some may pass 
a copy of the actual parameter.

-- 
Jeff Carter
"Have you gone berserk? Can't you see that that man is a ni?"
Blazing Saddles




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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
                   ` (5 preceding siblings ...)
  2002-10-05  2:14 ` SteveD
@ 2002-10-08  9:53 ` John McCabe
  2002-10-08 15:37   ` Matthew Heaney
  2002-10-08 10:21 ` Preben Randhol
  7 siblings, 1 reply; 28+ messages in thread
From: John McCabe @ 2002-10-08  9:53 UTC (permalink / raw)


On Fri, 04 Oct 2002 02:14:44 +0000, "Rick Duley"
<rickduley@hotmail.com> wrote:

>1.   All the texts I can find which deal in any degree at all with OO in Ada 
>teach that the tagged record in an object declaration should be 'private'.  
>When you follow this line, a derived class does not have direct access to 
>the object attributes of the base class, i.e. _there_is_no_inheritace_.

If you make the tagged type declaration private and still want
inheritance your extensions of the tagged type must be created in
child packages of the original tagged type.

>2.   To provide the derived class with access to the object attributes of 
>the base class I have to create user-defined methods in the base class.  

You shouldn't have to do this if you leave the tagged type declaration
public, *or* create the tagged extension in a child package of the
package declaring the base class.

>3.   If the tagged record in the base class is left public and the derived 
>class is in a child package of the package defining the base class, then the 
>base class attributes are accessible to the derived class.  So far so good 

True, but the base class attributes will also be accessible to the
derived class if it is in a child package and the tagged type is
private. A child package always has visibility of its parents' private
parts (so to speak).

>:)  However, if in a program 'use'ing the child package of 'Thick_Pen' (and 
>not mentioning the base package of 'Pen') I make a call to the routine 
>'Draw' with an actual parameter of the type 'Pen' I get a compiler error 
>message to the effect that 'Draw' is not visible.  In other words, Thick_Pen 
>has not inherited the operation Draw for 'Pen'  Again, 
>_there_is_no_inheritace_.

There is an easy answer to this that I can't remember at the moment.
It's probably to do with using 'Class somewhere, but it may be that
you have an incorrect declaration somewhere that isn't actually a
creating a dispatching operation.

>4.  Further along that line, Thick_Pen does not inherit the type Pen so I 
>cannot declare a Pen (or Pen_Access) unless I 'with' and 'use' the package 
>in which Pen is declared.  This means that making the package in which 
>Thick_Pen is declared a child of the package in which Pen is declared 
>totally useless.  _There_is_no_inheritance_!


>I have to say that this is the first time in pretty near a decade I have 
>been writing in and teaching with Ada that Ada hasn't come up with the 
>goods.  Do I labour under some serious misunderstanding, do I have something 
>terribly wrong?

Basically you are making some assumptions based on what you appear to
expect from an object-orientated programming language rather than
looking at the details of how O-O is implemented in Ada 95. Admittedly
the Ada 95 implementation can be a pain in the arse sometimes,
especially if you're used to using C++ and Jave, but there are
generally good reasons for why things are done the way they are. You
need to look at the Rationale to find them out a lot of the time.

>5.   One final thing (for this time anyway ;), why is it that that Ada does 
>not use the intuitive 'object.method' syntax for making calls to and object. 

Go to www.adaic.org and find the Ada 95 Rationale. I believe this is
discussed in there, as are pretty much all of the questions you have
asked to some extent.

>If there are people working on Ada0x then maybe we shoo\uld be putting this 
>forward for consideration.

You haven't been looking at this newsgroup much have you :-)

As David mentioned, it would be worth providing code for this question
rather than your nice class diagrams as the code may tell a different
story.




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

* Re: OO in Ada
  2002-10-04  2:14 OO in Ada Rick Duley
                   ` (6 preceding siblings ...)
  2002-10-08  9:53 ` John McCabe
@ 2002-10-08 10:21 ` Preben Randhol
  7 siblings, 0 replies; 28+ messages in thread
From: Preben Randhol @ 2002-10-08 10:21 UTC (permalink / raw)


On Fri, 04 Oct 2002 02:14:44 +0000, Rick Duley wrote:
> Hi all

[...]

> Do I labour under some serious misunderstanding, do I have something 
> terribly wrong?

Afraid so, but read this:

   http://www.it.bton.ac.uk/staff/je/adacraft/part3.htm
   http://www.it.bton.ac.uk/staff/je/adacraft/ch04.htm#4.8
   http://goanna.cs.rmit.edu.au/~dale/ada/aln/14_OO.html

   more can be found here:
   http://burks.bton.ac.uk/burks/language/ada/ada95.pdf (from p 169)

> 
> 5.   One final thing (for this time anyway ;), why is it that that Ada does 
> not use the intuitive 'object.method' syntax for making calls to and object. 
>    This would mean that (in the case described in section 3) the call would 
> read
> 
> 	Pen.Draw(To_X => n, To_Y => n);
> 
> and with inheritance this would be accessible through the child package 
> declaring Thick_Pen.  While I'm okay with using the existing syntax, I feel 
> the 'object.method' syntax is more intuitive and in line with OO thinking.  
> If there are people working on Ada0x then maybe we should be putting this 
> forward for consideration.

No. Read: http://www.adapower.com/articles/class.html

Preben
-- 
Ada95 is good for you.
http://libre.act-europe.fr/Software_Matters/02-C_pitfalls.pdf



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

* Re: OO in Ada
  2002-10-08  9:53 ` John McCabe
@ 2002-10-08 15:37   ` Matthew Heaney
  2002-10-08 16:47     ` Georg Bauhaus
  2002-10-08 17:16     ` Warren W. Gay VE3WWG
  0 siblings, 2 replies; 28+ messages in thread
From: Matthew Heaney @ 2002-10-08 15:37 UTC (permalink / raw)



"John McCabe" <john.nospam@nospamassen.nospamdemon.co.uk> wrote in message
news:3da2aafd.7023559@news.demon.co.uk...
>
> If you make the tagged type declaration private and still want
> inheritance your extensions of the tagged type must be created in
> child packages of the original tagged type.

This isn't quite right.  There is *always* inheritance when a type derives
from another type.  If the parent type is tagged, then you're allowed to
extend the parent type's representation.

What you really meant is that you don't have *visibility* to the parent's
private presentation, unless the type is declared in a child package.

If you derive from a type, you always inherit its representation and
operations (that's what "primitive  operation" means).

> >:)  However, if in a program 'use'ing the child package of 'Thick_Pen'
(and
> >not mentioning the base package of 'Pen') I make a call to the routine
> >'Draw' with an actual parameter of the type 'Pen' I get a compiler error
> >message to the effect that 'Draw' is not visible.  In other words,
Thick_Pen
> >has not inherited the operation Draw for 'Pen'  Again,
> >_there_is_no_inheritace_.
>
> There is an easy answer to this that I can't remember at the moment.
> It's probably to do with using 'Class somewhere, but it may be that
> you have an incorrect declaration somewhere that isn't actually a
> creating a dispatching operation.

Yes, something is indeed wrong with the parent declaration.  If the
operation is primitive, then it gets inherited.
_There_is_always_inheritance_of_primitive_operations.

> >5.   One final thing (for this time anyway ;), why is it that that Ada
does
> >not use the intuitive 'object.method' syntax for making calls to and
object.

Why is

package P is
   type T is tagged limited private;
   function "=" (L, R : T) return Boolean;
  ...
end;

any different from:

namespace N
{
   class C
   {
      ...
   private:
      C& operator=(const C&);
      C(const C&);
   };

   bool operator==(const C& lhs, const C& rhs);
}

Are you saying binary operations in C++ aren't intuitive?

If I do this:
   Push_Back (List, Item);

then is there any question that I'm appending a new element, with the value
Item, to the back of object List?







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

* Re: OO in Ada
  2002-10-08 15:37   ` Matthew Heaney
@ 2002-10-08 16:47     ` Georg Bauhaus
  2002-10-08 17:48       ` Matthew Heaney
  2002-10-08 17:16     ` Warren W. Gay VE3WWG
  1 sibling, 1 reply; 28+ messages in thread
From: Georg Bauhaus @ 2002-10-08 16:47 UTC (permalink / raw)


Matthew Heaney <mheaney@on2.com> wrote:
:   Push_Back (List, Item);
: 
: then is there any question that I'm appending a new element, with the value
: Item, to the back of object List?

From a different perspective, isn't "pushing back" different
from "appending" in standard English?  (I'm asking this because
I don't known English well, so I might miss something.)

So, will I have to know the meaning "append" of "push_back" (as
opposed to "push_front" for "prepend"), and infer the meaning
from the context (List, Item)? Or from Stepanov's (and Musser's?)
popular (and standardized, so there...) wording?

That is to say, shouldn't there be an "onto" part or similar
in the Push_Back?

-- Georg



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

* Re: OO in Ada
  2002-10-08 15:37   ` Matthew Heaney
  2002-10-08 16:47     ` Georg Bauhaus
@ 2002-10-08 17:16     ` Warren W. Gay VE3WWG
  2002-10-08 17:58       ` Matthew Heaney
  1 sibling, 1 reply; 28+ messages in thread
From: Warren W. Gay VE3WWG @ 2002-10-08 17:16 UTC (permalink / raw)


Matthew Heaney wrote:
> "John McCabe" <john.nospam@nospamassen.nospamdemon.co.uk> wrote in message
> news:3da2aafd.7023559@news.demon.co.uk...
...
>>>:)  However, if in a program 'use'ing the child package of 'Thick_Pen'
>>
> (and
>>>not mentioning the base package of 'Pen') I make a call to the routine
>>>'Draw' with an actual parameter of the type 'Pen' I get a compiler error
>>>message to the effect that 'Draw' is not visible.  In other words,
>>
> Thick_Pen
> 
>>>has not inherited the operation Draw for 'Pen'  Again,
>>>_there_is_no_inheritace_.
>>
>>There is an easy answer to this that I can't remember at the moment.
>>It's probably to do with using 'Class somewhere, but it may be that
>>you have an incorrect declaration somewhere that isn't actually a
>>creating a dispatching operation.

I believe that the problem referred to here is simply one
of a visibility. Either a 'use' or a fully qualified call is
required. If I understand correctly, you're saying you have
some parent package "Pen", and a child package "Thick_Pen",
and you use the package as in:

   use Pen.Thick_Pen;
   ...
   Draw(...); -- Compile error because Draw is defined in Pen


This is solved either by doing something like:

   use Pen, Pen.Thick_Pen;
   ...
   Draw(...);  -- OK now, because Pen.Draw is visible.


or qualifying by your call as in:

   use Pen.Thick_Pen;
   ...
   Pen.Draw(...);

Warren.
-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




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

* Re: OO in Ada
  2002-10-08 16:47     ` Georg Bauhaus
@ 2002-10-08 17:48       ` Matthew Heaney
  0 siblings, 0 replies; 28+ messages in thread
From: Matthew Heaney @ 2002-10-08 17:48 UTC (permalink / raw)



"Georg Bauhaus" <sb463ba@l1-hrz.uni-duisburg.de> wrote in message
news:anv27t$jrs$1@a1-hrz.uni-duisburg.de...
> Matthew Heaney <mheaney@on2.com> wrote:
> :   Push_Back (List, Item);
> :
> : then is there any question that I'm appending a new element, with the
value
> : Item, to the back of object List?
>
> From a different perspective, isn't "pushing back" different
> from "appending" in standard English?  (I'm asking this because
> I don't known English well, so I might miss something.)

They are the same thing.

The example comes from Charles, which is a library modeled in the C++ STL.
I actually considered using the name Append instead of Push_Back (this would
be more consistent with names used in Ada.Strings.*), but I went ahead and
used Push_Back, to be consistent with Pop_Back.

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


> So, will I have to know the meaning "append" of "push_back" (as
> opposed to "push_front" for "prepend"), and infer the meaning
> from the context (List, Item)? Or from Stepanov's (and Musser's?)
> popular (and standardized, so there...) wording?

The name is identical to the STL, so if you understand what

   list.push_back(item);

means, then it should be obvious what

   Push_Back (List, Item)

means, too.


> That is to say, shouldn't there be an "onto" part or similar
> in the Push_Back?

There is a tradition in Ada that the first parameter of a primitive
operation of a user-defined type be the "target" of the operation, that's
why the Push_Back operation has the parameter order it does.

For example, if I see this:

   Write (File, Item);

then it seems obvious (to me) that the operation is writing Item to the file
object File.







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

* Re: OO in Ada
  2002-10-08 17:16     ` Warren W. Gay VE3WWG
@ 2002-10-08 17:58       ` Matthew Heaney
  2002-10-09 16:59         ` Warren W. Gay VE3WWG
  0 siblings, 1 reply; 28+ messages in thread
From: Matthew Heaney @ 2002-10-08 17:58 UTC (permalink / raw)



"Warren W. Gay VE3WWG" <ve3wwg@cogeco.ca> wrote in message
news:3DA31301.80506@cogeco.ca...
>
> I believe that the problem referred to here is simply one
> of a visibility. Either a 'use' or a fully qualified call is
> required.

No.  Primitive operations for a type are inherited during a derivation (it
doesn't matter what kind of type the parent is), and are therefore
"implicitly declared" immediately following the declaration of the derived
type.

For example:

package P is
   type T is range 0 .. 10;
   procedure Op (O : in T);
end:

with P;
package Q is
   type NT is new P.T;
end;

There is an operation called Op implicitly declared for Q.NT.  To call it
you do NOT have to with P.  For example:

declare
   use Q;
   O : NT;
begin
   Op (O);
end;

Op does NOT need any qualification, because it's already declared in Q, and
the operations in Q (even implicitly declared operations) are directly
visible (here, because use Q).


> If I understand correctly, you're saying you have
> some parent package "Pen", and a child package "Thick_Pen",
> and you use the package as in:
>
>    use Pen.Thick_Pen;
>    ...
>    Draw(...); -- Compile error because Draw is defined in Pen

The Draw operation that takes a thick pen type is (implicitly) declared in
package Thick_Pen.  There is NO compile error.  It doesn't even matter
whether package Think_Pen is a child of Pen.

Primitive operations of a type are inherited during a derivation.  That's
what it means for an operation to be "primitive."

> This is solved either by doing something like:
>
>    use Pen, Pen.Thick_Pen;
>    ...
>    Draw(...);  -- OK now, because Pen.Draw is visible.

This will NOT compile, because Pen.Draw takes Pen_Type, not Thick_Pen_Type.

> or qualifying by your call as in:
>
>    use Pen.Thick_Pen;
>    ...
>    Pen.Draw(...);

No.  This won't compile either.  You need to say:

Pen.Thick_Pen.Draw(...);









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

* Re: OO in Ada
  2002-10-06  3:00         ` Jim Rogers
@ 2002-10-08 21:08           ` Gisle Sælensminde
  0 siblings, 0 replies; 28+ messages in thread
From: Gisle Sælensminde @ 2002-10-08 21:08 UTC (permalink / raw)


In article <3D9FA70C.1070407@worldnet.att.net>, Jim Rogers wrote:
>> 
>> Yes, but that subprogram can take multiple parameters of that type,
>> and when a call is made to that subprogram with arguments which are
>> classwide, they must all have the same dynamic type (which is then
>> used in the dispatch) or an exception results.
> 
> 
> You are correct. There is a little more that needs to be said about
> this.
> 
> Following is a quote from "Ada as a Second Language" 2nd Edition by
> Norman Cohen (Section 12.4.4.3)

Even you have the generic method approch in Ada, which could have 
supported multiple displatching. This ulike the message passing approch
(object.method() ), that syntactically prevents you from doing it.
As far as I can see there is no need for extra syntax for adding
multiple dispatching in Ada. You would however need a lot of additional
semantics, including how the right method should be selected, and a lot
of special cases that would have to defined semantics.I would guess 
that one reason that it is not in the standard, is that it would
add a lot of complexity to the standard, which again would have made it
harder to implement conforming compilers. 

Other languages, like Common Lisp, where the object system is known as 
CLOS does multiple dispatching this way.  

--
Gisle S�lensminde ( gisle@ii.uib.no )   

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going
to land, and it could be dangerous sitting under them as they fly
overhead. (from RFC 1925)



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

* Re: OO in Ada
  2002-10-07 14:10   ` Matthew Heaney
  2002-10-07 19:52     ` Jeffrey Carter
@ 2002-10-08 21:18     ` Dmitry A.Kazakov
  1 sibling, 0 replies; 28+ messages in thread
From: Dmitry A.Kazakov @ 2002-10-08 21:18 UTC (permalink / raw)


Matthew Heaney wrote:

> "SteveD" <nospam_steved94@attbi.com> wrote in message
> news:JVrn9.40015$FO4.9224@sccrnsc03...
>>
>> In C++ there is a hidden "this" pointer quietly hiding in the background
>> that you must be very much aware of (if you're doing any serious
>> programming).  In Ada this is an explicit variable passed into the
>> procedure.
> 
> This is also true in Ada, wrt passing unconstrained arrays:
> 
> procedure Op (S : String) is
> 
> You're actually passing a descriptor on the stack, which contains info
> about
> the string's length and index range.  So here there is "hidden"
> information being passed too, not unlike an implicit this-ptr in C++.

There are other examples where Ada follows this approach: protected objects 
and tasks. They do have prefix syntax of entry point calls and a hidden 
parameter:

task type A is
   entry Do_It;
end A;
...
X : A;
...
X.Do_It; -- X is a hidden parameter

Same as with C++, this approach works no longer a subroutine has exactly 
one "special" parameter. For example, should we allow in Ada rendezvous 
with several tasks, then the prefix syntax should be replaced by explicit 
parameter passing:

task type A;
task type B;
entry Do_It (X : in out A; Y : in out B); -- This is not Ada!
...
X : A; Y : B;

Do_It (X, Y); -- This is not Ada!

-- 
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



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

* Re: OO in Ada
  2002-10-08 17:58       ` Matthew Heaney
@ 2002-10-09 16:59         ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 28+ messages in thread
From: Warren W. Gay VE3WWG @ 2002-10-09 16:59 UTC (permalink / raw)


Matthew Heaney wrote:
> "Warren W. Gay VE3WWG" <ve3wwg@cogeco.ca> wrote in message
> news:3DA31301.80506@cogeco.ca...
> 
>>I believe that the problem referred to here is simply one
>>of a visibility. Either a 'use' or a fully qualified call is
>>required.
> 
> No.  Primitive operations for a type are inherited during a derivation (it
> doesn't matter what kind of type the parent is), and are therefore
> "implicitly declared" immediately following the declaration of the derived
> type.

You're absolutely right. I wasn't thinking this all the way
through.  I'll go back to my own code now ;-)

-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




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

end of thread, other threads:[~2002-10-09 16:59 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-04  2:14 OO in Ada Rick Duley
2002-10-04  2:55 ` Jim Rogers
2002-10-04 17:35   ` Hyman Rosen
2002-10-05  0:20     ` Jim Rogers
2002-10-05 23:38       ` Dmitry A.Kazakov
2002-10-05 15:25         ` Jim Rogers
2002-10-06 21:37           ` Dmitry A.Kazakov
2002-10-06  2:18       ` Hyman Rosen
2002-10-06  3:00         ` Jim Rogers
2002-10-08 21:08           ` Gisle Sælensminde
2002-10-04  3:37 ` Chad R. Meiners
2002-10-04  5:32 ` Simon Wright
2002-10-04  6:01 ` tmoran
2002-10-04 15:05 ` Matthew Heaney
2002-10-05  2:14 ` SteveD
2002-10-05  8:54   ` Preben Randhol
2002-10-07 14:10   ` Matthew Heaney
2002-10-07 19:52     ` Jeffrey Carter
2002-10-08 21:18     ` Dmitry A.Kazakov
2002-10-08  9:53 ` John McCabe
2002-10-08 15:37   ` Matthew Heaney
2002-10-08 16:47     ` Georg Bauhaus
2002-10-08 17:48       ` Matthew Heaney
2002-10-08 17:16     ` Warren W. Gay VE3WWG
2002-10-08 17:58       ` Matthew Heaney
2002-10-09 16:59         ` Warren W. Gay VE3WWG
2002-10-08 10:21 ` Preben Randhol
  -- strict thread matches above, loose matches on Subject: below --
1998-05-15  0:00 Gisle S{lensminde

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