comp.lang.ada
 help / color / mirror / Atom feed
* Ada95 OOP Questions
@ 1996-07-28  0:00 Spasmo
  1996-07-28  0:00 ` David C. Hoos, Sr.
                   ` (11 more replies)
  0 siblings, 12 replies; 46+ messages in thread
From: Spasmo @ 1996-07-28  0:00 UTC (permalink / raw)



Hi.

	First off thanks for all the help I've gotten here already.
I'm currently cranking out some code to get familiarized with Ada
and it's going wonderfully.  Now with that in mind what I have
to ask is a bit long winded and maybe a bit vague, but I'll try
to put it as best as I can.

Ok, with regards to OOP, my previous experience has been with
C++.  In that language when you declare a class, it consists of
data (which can be at various visibility levels (ie: private)),
and methods which operate on the data in the class.  What this
results in is an object (loose use) that has its own actions
and its own attributes so that it's a self contained entity
so to speak.  For instance here's a crude idea:

	class Person {
		public:
			void Walk();
			void Talk();
			void Eat();
		private:
			int Age;
			char Name[256];
	};

When an instance of Person is declared, you just make calls
to the functions provided in that class and all the data
associated with Person is kept inside it and manipulated in it.
You can of course inherit, use polymorphism, etc...

Well after looking at Barnes' Ada95 book and checking out the
OOP sections I noticed that the Objects in Ada95 seem to
consist purely of data, and no methods seem to be involved
so that you have to pass these objects to functions in order
to get stuff done.  Am I wrong in this (or did I somehow 
miss something again?).

In any case I've been looking at using private Objects inside
packages and using these objects as package-global variables
to all the procedures/functions involved so that one can
simulate this sort of behavior, although the simulation
isn't perfect.  Well my other question has to do with
whether or not I should do this?  I mean I have a decent
grasp of using Ada for programming, but am I truly programming
in Ada?  Am I trying to program in C++, but I just happen to
be using Ada to do it?  What is the consensus on this, and
also would anyone describe the philosophy behind this
implementation of OOP?

I'm being careful because I also was confused as to tasks not
seeming to employ time-slices in my implementation only to
realize that it was a blessing in disguise, so I'm approaching
this OO implementation in the same way, namely that there
is something inherent that I am not getting that makes this
a very good thing.

Thanks and I hope my question was somewhat understandable.


--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
@ 1996-07-28  0:00 ` David C. Hoos, Sr.
  1996-07-28  0:00   ` Spasmo
  1996-07-28  0:00 ` Andre Spiegel
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: David C. Hoos, Sr. @ 1996-07-28  0:00 UTC (permalink / raw)



Classes in Ada95 and C++ are very different.  For a treatment of the OOP
aspects of Ada95 see Smith, Michael A., "Object-Oriented Software in Ada
95".  In this book, a suitable style for Ada95 classes is presented.  It's
not the only way it can be done, but provides at least a good starting
point.
-- 
David C. Hoos, Sr.,
http://www.dbhwww.com
http://www.ada95.com 






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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 ` Andre Spiegel
@ 1996-07-28  0:00   ` Spasmo
  1996-07-29  0:00     ` Thomas Kendelbacher
                       ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: Spasmo @ 1996-07-28  0:00 UTC (permalink / raw)



Andre Spiegel (spiegel@berlin.informatik.uni-stuttgart.de) wrote:
: Spasmo writes:

: > Well after looking at Barnes' Ada95 book and checking out the
: > OOP sections I noticed that the Objects in Ada95 seem to
: > consist purely of data, and no methods seem to be involved
: > so that you have to pass these objects to functions in order
: > to get stuff done.  Am I wrong in this (or did I somehow 
: > miss something again?).


[Snip]

: So, to translate your C++ example into equivalent Ada (not just
: "simulating" it!), you can write


:    package Persons is

:       type Person is tagged private;

:       procedure Walk (P : Person);
:       procedure Talk (P : Person);
:       procedure Eat  (P : Person);

:    private

:       type Person is tagged
:          record


:             Age  : Integer;  -- rather "Natural", I'd suggest 
:                              -- (C++ doesn't have this)

Or even better, a subtype.  That's what I like about Ada.



:             Name : String (1..256);
:          end record;

:    end Persons;


Well here's the thing though, from what I'm seeing when you
use the package you'd need to pass the parameters to the
subprograms rather than having the data encapsulated.  For
instance in C++ you'd do the following:

	Person p;
	p.walk();
	p.talk();
	p.eat();

But with the above you'd do something like the following:
(Any Ada code provided may be slightly erroneous, I just want
to give a general idea of what I think I understand hence not
checking much).


with Persons;

procedure Main is

	P : Persons.Person;

begin
	Persons.Walk(P);
	Persons.Talk(P);
	Persons.Eat(P);
end Main;

Correct me if I'm wrong on this.  So you're still passing parameters
which means that data and subprograms are still 2 different entities
which sorta hurts the abstraction, rather than in say C++ where 
you've got a unified object.   

That's pretty much what I was talking about.  I'm not saying that
one is necessarily worse than the other, I was just wondering if
there was a rationale for doing it that particular way in Ada
rather than a unified object that was like a combination of 
data and subprograms that enabled it to smoothly simulate an
entity?

Also there's another slight difference -- inheritance.  From
what I'm seeing, if we wanted to create say a SuperPersons
package that inherited from persons we'd create a new package
called SuperPerson, then we'd with the Persons package, and
provide "wrappers" for everything defined in the Persons
package right?  Then we'd of course inherit from the data
types and add in any new functionality that we wanted to,
am I correct?

For example here's a crude idea of what I'm talking about:

with Persons;
package SuperPersons is

	type SuperPerson is tagged private;

		procedure Walk(SP : SuperPerson);
		procedure Talk(SP : SuperPerson);
		procedure Eat(SP : SuperPerson);

	private

	type SuperPerson is new Persons.Person with
		record
			SuperPowers : Power;
		end record;

end SuperPersons;

then all our procedures like Walk, Talk, Eat, etc... would need
to call their predecessors right?  For instance:

package body SuperPersons is

	procedure Walk(SP : SuperPerson) is
	begin
		Persons.Walk(SP);
	end Walk;


	...


end SuperPersnos;

and so forth (we could inline them)

Am I correct or can we in fact inherit operations without manually
providing wrappers for the predecessors?



: What should be pointed out is that C++ and Ada use slightly different
: abstractions.  In C++, you have "classes" and "objects" (but sometimes
: a class is referred to as an object, too); whereas in Ada you have 
: "packages", "types", "classes of types", and "objects".  For a very
: good discussion of this, see Tucker Taft's answer to Question 5.1 in
: the Ada Programming FAQ (http://lglwww.epfl.ch/Ada/FAQ/programming.html).

Well what I learned in C++ was that "class" referred to the declaration/
definition, whereas an object is an instance of a class.  So using
my old example, Person is a class, but p is an object since it's an
instance of Person.  Still that is kinda moot since we're more concerned
with Ada rather than C++.  I'll look at Question 5.1 again (I skimmed
over certain parts of the FAQ last time I read it which was when
I was trying to find out more about Ada to see whether or not I'd
want to program in it).


: Hope this helps,

It did, thanks.



: Andre Spiegel
: University of Stuttgart, Germany

--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 ` David C. Hoos, Sr.
@ 1996-07-28  0:00   ` Spasmo
  0 siblings, 0 replies; 46+ messages in thread
From: Spasmo @ 1996-07-28  0:00 UTC (permalink / raw)



David C. Hoos, Sr. (david.c.hoos.sr@ada95.com) wrote:
: Classes in Ada95 and C++ are very different.  For a treatment of the OOP
: aspects of Ada95 see Smith, Michael A., "Object-Oriented Software in Ada
: 95".  In this book, a suitable style for Ada95 classes is presented.  It's
: not the only way it can be done, but provides at least a good starting
: point.

Cool.  I'll try to find that book -- thanks.


: -- 
: David C. Hoos, Sr.,
: http://www.dbhwww.com
: http://www.ada95.com 



--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
  1996-07-28  0:00 ` David C. Hoos, Sr.
@ 1996-07-28  0:00 ` Andre Spiegel
  1996-07-28  0:00   ` Spasmo
  1996-07-29  0:00 ` Andre Spiegel
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 46+ messages in thread
From: Andre Spiegel @ 1996-07-28  0:00 UTC (permalink / raw)



Spasmo writes:

> Well after looking at Barnes' Ada95 book and checking out the
> OOP sections I noticed that the Objects in Ada95 seem to
> consist purely of data, and no methods seem to be involved
> so that you have to pass these objects to functions in order
> to get stuff done.  Am I wrong in this (or did I somehow 
> miss something again?).

Ada Objects "consist" of both data and methods, just like in any other
OOP language.  Ada calls the methods "primitive subprograms", and they
are (roughly) defined as those subprograms

  "that are explicitly declared immediately within the same
   package_specification and that operate on the type." (RM95 3.2.3;6)

So, to translate your C++ example into equivalent Ada (not just
"simulating" it!), you can write


   package Persons is

      type Person is tagged private;

      procedure Walk (P : Person);
      procedure Talk (P : Person);
      procedure Eat  (P : Person);

   private

      type Person is tagged
         record
            Age  : Integer;  -- rather "Natural", I'd suggest 
                             -- (C++ doesn't have this)
            Name : String (1..256);
         end record;

   end Persons;


What should be pointed out is that C++ and Ada use slightly different
abstractions.  In C++, you have "classes" and "objects" (but sometimes
a class is referred to as an object, too); whereas in Ada you have 
"packages", "types", "classes of types", and "objects".  For a very
good discussion of this, see Tucker Taft's answer to Question 5.1 in
the Ada Programming FAQ (http://lglwww.epfl.ch/Ada/FAQ/programming.html).

Hope this helps,

Andre Spiegel
University of Stuttgart, Germany




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

* Re: Ada95 OOP Questions
  1996-07-29  0:00 ` Andre Spiegel
@ 1996-07-29  0:00   ` David Wheeler
  1996-07-30  0:00     ` Spasmo
  1996-07-30  0:00     ` Spasmo
  1996-07-29  0:00   ` Thomas Kendelbacher
  1 sibling, 2 replies; 46+ messages in thread
From: David Wheeler @ 1996-07-29  0:00 UTC (permalink / raw)



Andre Spiegel (spiegel@berlin.informatik.uni-stuttgart.de) wrote:
: Spasmo writes:

: > with Persons;
: > 
: > procedure Main is
: > 
: > 	P : Persons.Person;
: > 
: > begin
: > 	Persons.Walk(P);
: > 	Persons.Talk(P);
: > 	Persons.Eat(P);
: > end Main;

: With a use-clause, it looks better

:     with Persons; use Persons;

:     P : Person;

:     Walk (P);
:     Talk (P);
:     Eat  (P);

: > Correct me if I'm wrong on this.  So you're still passing parameters
: > which means that data and subprograms are still 2 different entities
: > which sorta hurts the abstraction, rather than in say C++ where 
: > you've got a unified object.   

: You _are_ wrong.  The subprograms actually _are_ a part of the object,
: and they "go" with it, so to speak of, whereever you take the object.
: It is just less obvious from the syntax in Ada.

Spiegel's right.  Spasmo - you're concentrating on minor syntactic variance.
Ada treats all calls with the same syntax; C++'s syntax varies depending
on how it's defined.  The difference is unimportant.

To see an example of OO in Ada95, look at my "Small" program at:
  "http://lglwww.epfl.ch/Ada/Tutorials/Lovelace/small.htm"
You'll see lots of OO concepts, and operations unified with the object.


--- David A. Wheeler
Net address: dwheeler@ida.org





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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
  1996-07-28  0:00 ` David C. Hoos, Sr.
  1996-07-28  0:00 ` Andre Spiegel
@ 1996-07-29  0:00 ` Andre Spiegel
  1996-07-29  0:00   ` David Wheeler
  1996-07-29  0:00   ` Thomas Kendelbacher
  1996-07-30  0:00 ` Andre Spiegel
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 46+ messages in thread
From: Andre Spiegel @ 1996-07-29  0:00 UTC (permalink / raw)



Spasmo writes:

> with Persons;
> 
> procedure Main is
> 
> 	P : Persons.Person;
> 
> begin
> 	Persons.Walk(P);
> 	Persons.Talk(P);
> 	Persons.Eat(P);
> end Main;

With a use-clause, it looks better

    with Persons; use Persons;

    P : Person;

    Walk (P);
    Talk (P);
    Eat  (P);

> Correct me if I'm wrong on this.  So you're still passing parameters
> which means that data and subprograms are still 2 different entities
> which sorta hurts the abstraction, rather than in say C++ where 
> you've got a unified object.   

You _are_ wrong.  The subprograms actually _are_ a part of the object,
and they "go" with it, so to speak of, whereever you take the object.
It is just less obvious from the syntax in Ada.

At the implementation level, C++ does things in just the same way as
Ada.  The object *is* actually passed as a parameter to its functions,
although this parameter (the "this" pointer) is implicitly generated.
C++ has a special syntax for method invocation ("p.walk()"), which is
converted to a normal function call with "this=p" as the first
parameter by the compiler.  That is the only difference between C++
and Ada here.  (There are a number of implications of this, though;
mostly concerning the fact that Ada can bind some calls statically,
whereas in C++ you always need to go through the dispatch table in the
object.  I won't go into detail about this here.  Ada gives you finer
control about the calling mechanism, that's the point.)

When you inherit from a type in Ada (extend the type), you certainly
don't need to write the subprograms again -- that's the whole point of
inheritance.  The do "go" with the type; you only need to rewrite
them if you want to change them in the derived type.  No difference
between Ada and C++ here.  The example given in your message is wrong.




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00   ` Spasmo
@ 1996-07-29  0:00     ` Thomas Kendelbacher
  1996-07-31  0:00       ` Spasmo
  1996-08-01  0:00       ` Jon S Anthony
  1996-07-30  0:00     ` David Wheeler
  1996-07-30  0:00     ` Ken Garlington
  2 siblings, 2 replies; 46+ messages in thread
From: Thomas Kendelbacher @ 1996-07-29  0:00 UTC (permalink / raw)



In article <4tgi88$5fi@Masala.CC.UH.EDU>, cosc19z5@Bayou.UH.EDU (Spasmo) writes:
>Well here's the thing though, from what I'm seeing when you
>use the package you'd need to pass the parameters to the
>subprograms rather than having the data encapsulated.  For
>instance in C++ you'd do the following:
>
>	Person p;
>	p.walk();
>	p.talk();
>	p.eat();
>
>But with the above you'd do something like the following:
>(Any Ada code provided may be slightly erroneous, I just want
>to give a general idea of what I think I understand hence not
>checking much).
>
>with Persons;
>procedure Main is
>	P : Persons.Person;
>begin
>	Persons.Walk(P);
>	Persons.Talk(P);
>	Persons.Eat(P);
>end Main;
>
>Correct me if I'm wrong on this.  So you're still passing parameters
>which means that data and subprograms are still 2 different entities
>which sorta hurts the abstraction, rather than in say C++ where 
>you've got a unified object.   

See it from this point of view: It's just a different syntax for the
same thing ("p.walk()" vs. "Walk(P)"), and putting the object P in front
is just some syntactic sugar in C++ which is translated basically to the
same code - a reference to the object is passed to the function as its
first parameter.

>That's pretty much what I was talking about.  I'm not saying that
>one is necessarily worse than the other, I was just wondering if
>there was a rationale for doing it that particular way in Ada
>rather than a unified object that was like a combination of 
>data and subprograms that enabled it to smoothly simulate an
>entity?

The Ada way of writing this comes from the tradition of "abstract data
types," where a type is defined by the operations declared on it.
So, there's definitely a conceptual connection between data and subprograms.

>Also there's another slight difference -- inheritance.  From
>what I'm seeing, if we wanted to create say a SuperPersons
>package that inherited from persons we'd create a new package
>called SuperPerson, then we'd with the Persons package, and
>provide "wrappers" for everything defined in the Persons
>package right?  Then we'd of course inherit from the data
>types and add in any new functionality that we wanted to,
>am I correct?
>
> [.. example recoding the Persons operations for a derived type ..]
>
>Am I correct or can we in fact inherit operations without manually
>providing wrappers for the predecessors?

The latter is true: Even back in Ada 83, a derived type automatically
inherited all operations declared with the original type (in line with
the view of a type as "abstract data type"; the derived type would be
meaningless without the operations!)  This was of course preserved
by Ada 95; the difference is that Ada 95 now has tagged types, while
Ada 83 derived types were always incompatible with their parent types
(save by explicit conversion), and data extension was not directly
supported.

>Well what I learned in C++ was that "class" referred to the declaration/
>definition, whereas an object is an instance of a class.  So using
>my old example, Person is a class, but p is an object since it's an
>instance of Person.  Still that is kinda moot since we're more concerned
>with Ada rather than C++.  I'll look at Question 5.1 again (I skimmed
>over certain parts of the FAQ last time I read it which was when
>I was trying to find out more about Ada to see whether or not I'd
>want to program in it).

What's the big difference here? The type corresponds to the class, as it defines
public/private data and operations, and each value of the type (e.g. stored in a
variable) corresponds to an instance. It's not so much different from your C++
example: You wrote that in a C++ statement like "p.walk()", p "is" a Person
object; but to be exact, it is but a _name_ for the actual object (a variable,
just like in Ada.)

There is an essential difference between objects in C++ and Ada, though; in Ada,
you can't test for object identity as easily, like writing "this == that" in C++
(except if you explicitly switch to access types.) This can be a nuisance if
you're used to OO languages which support object identity directly, like C++ or
Smalltalk.
That's also a heritage from the abstract data type concept, whose mathematical
foundations don't deal with "identity" but with "equivalence."

-- 
Thomas Kendelbacher   |   email : Thomas.Kendelbacher@erno.de
DASA RI / Abt. RIT14  |   voice : +49 421 539 5492 (working hours)
Postfach 28 61 56     |      or : +49 421 57 04 37 (any other time)
D-28361 Bremen        |     fax : +49 421 539 4529 (any time)
Germany






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

* Re: Ada95 OOP Questions
  1996-07-29  0:00 ` Andre Spiegel
  1996-07-29  0:00   ` David Wheeler
@ 1996-07-29  0:00   ` Thomas Kendelbacher
  1996-08-02  0:00     ` Robert Dewar
  1 sibling, 1 reply; 46+ messages in thread
From: Thomas Kendelbacher @ 1996-07-29  0:00 UTC (permalink / raw)



In article <lhmvif7ny2a.fsf@berlin.berlin.informatik.uni-stuttgart.de>, Andre Spiegel <spiegel@berlin.informatik.uni-stuttgart.de> writes:
>Spasmo writes:
>
>> with Persons;
>> 
>> procedure Main is
>> 
>> 	P : Persons.Person;
>> 
>> begin
>> 	Persons.Walk(P);
>> 	Persons.Talk(P);
>> 	Persons.Eat(P);
>> end Main;
>
>With a use-clause, it looks better
>
>    with Persons; use Persons;
>
>    P : Person;
>
>    Walk (P);
>    Talk (P);
>    Eat  (P);

No, it doesn't look better, at least to me.
(OK, this is a 5-liner; consider a 'real' program.)

Having been working on large-scale Ada projects for years, I have learned
to avoid the use of use as much as possible.

As a consequence, I always try to find package names that create good-looking,
meaningful compound names when used in dot notation ("<pckg-name>.<proc-name>").

-- 
Thomas Kendelbacher   |   email : Thomas.Kendelbacher@erno.de
DASA RI / Abt. RIT14  |   voice : +49 421 539 5492 (working hours)
Postfach 28 61 56     |      or : +49 421 57 04 37 (any other time)
D-28361 Bremen        |     fax : +49 421 539 4529 (any time)
Germany






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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (4 preceding siblings ...)
  1996-07-30  0:00 ` Andre Spiegel
@ 1996-07-30  0:00 ` Robert I. Eachus
  1996-08-01  0:00 ` Jon S Anthony
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Robert I. Eachus @ 1996-07-30  0:00 UTC (permalink / raw)



In article <4tkbm8$oto@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

 > ...So what it is is that a subprogram really does belong to a class,
 > but the way we mark a subprogram as being a member of a class
 > is if it accepts that class as one of its parameters right?  So
 > we're still passing objects to subprograms but inheritance,
 > etc... are in fact performed, it's just the arguments that
 > "tag" (loose use of this term) a subprogram as a class method
 > and imply inheritance into other packages.

   Not quite.  A subprogram is inheritable if it is a primitive
operation of the type.  This basically means that it is declared in
the same package specification (implicitly or explicitly) and has a
parameter OR A RESULT of the type.

   A call to a primitive operation is dispatching if the type of the
controlling operand must be determined at run-time.  (If you declare
two or more tagged types in a single package, you cannot declare
subprograms which are dispatching operations of more than one of those
types.  RM 3.9.2(12) Just thought you might want to know.  Of course,
if you declare several tagged types in one scope, they are usually
related by derivation, so in practice this is not too restrictive.)

  The real nice thing about Ada though, is that you don't need to
understand what I just said.  Write the code you want, and either the
program will compile, link, and run, and do what you expected, or
compiler will complain.  (Most compiler error messages for these
obscure rules do not indicate a violation of the rule, but some other
bug.  So if you run into one of these HUH? error messages, check the
simple things first.  A typical case is that you copied the
declaration for a function on the parent, and changed the types of the
parameters, but forgot to change the result type.)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (3 preceding siblings ...)
  1996-07-30  0:00 ` Andre Spiegel
@ 1996-07-30  0:00 ` Andre Spiegel
  1996-07-30  0:00 ` Robert I. Eachus
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Andre Spiegel @ 1996-07-30  0:00 UTC (permalink / raw)



Spasmo writes:

> Here are things as I understand them (correct me if I'm wrong).

I'll do my very best ;).  In order to avoid confusion, you shouldn't
use the word "class" when referring to Ada programs this way.  "Class"
in Ada means something different (a hierarchy of types).  Each time
you wrote "class" in your message, you should replace it with "type",
and then it sounds pretty much correct.




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00   ` Spasmo
  1996-07-29  0:00     ` Thomas Kendelbacher
  1996-07-30  0:00     ` David Wheeler
@ 1996-07-30  0:00     ` Ken Garlington
  1996-08-04  0:00       ` Spasmo
  2 siblings, 1 reply; 46+ messages in thread
From: Ken Garlington @ 1996-07-30  0:00 UTC (permalink / raw)



Spasmo wrote:

> Well here's the thing though, from what I'm seeing when you
> use the package you'd need to pass the parameters to the
> subprograms rather than having the data encapsulated.  For
> instance in C++ you'd do the following:
> 
>         Person p;
>         p.walk();
>         p.talk();
>         p.eat();
> 
> But with the above you'd do something like the following:
> (Any Ada code provided may be slightly erroneous, I just want
> to give a general idea of what I think I understand hence not
> checking much).
> 
> with Persons;
> 
> procedure Main is
> 
>         P : Persons.Person;
> 
> begin
>         Persons.Walk(P);
>         Persons.Talk(P);
>         Persons.Eat(P);
> end Main;
> 
> Correct me if I'm wrong on this.  So you're still passing parameters
> which means that data and subprograms are still 2 different entities
> which sorta hurts the abstraction, rather than in say C++ where
> you've got a unified object.

Depends on what you're abstrating. If you don't want an abstract data type,
but you want a generic abstract data object, why not do this:

  generic
  package Person is

    procedure Walk;
    procedure Talk;
    procedure Eat;

  private

    type Person_Type is -- as before
    Object : Person_Type;

  end Person;

Translating your C++ code:

   package P is new Person;  -- Person p;
   P.Walk;                   -- p.walk();
   P.Talk;                   -- p.talk();
   P.Eat;                    -- p.eat();

Note, however, that there are things you can't do with a GADO (like
make an array of Persons) that you can do with an ADT.

If your complaint is that you like p.eat() better than eat(p), on the
other hand, then I don't see this as an abstraction difference - just
a syntax difference.

Just out of curiousity, if Person is declared in the C++ equivalent of
a package (and I forget the nomenclature -- space?), what does your C++
code look like?

-- 
LMTAS - "Our Brand Means Quality"




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (2 preceding siblings ...)
  1996-07-29  0:00 ` Andre Spiegel
@ 1996-07-30  0:00 ` Andre Spiegel
  1996-07-30  0:00 ` Andre Spiegel
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Andre Spiegel @ 1996-07-30  0:00 UTC (permalink / raw)



Spasmo writes:

> Well I can live with passing parameters but still the question
> of inheriting operations from a parent class defined in a
> different module is IMO a big deal.

There is no problem with this, whatsoever.  Your inheriting type can be
in a different package than the base type, or in the same package, it
doesn't matter.

(One more thought on the issue of subprograms being a part of the
object: certainly the code of each subprogram exists only once in the
system -- even if there are ever so many objects of the same type.  So
the actual object definitely needs to be passed as a parameter to the
subprogram.  That is true for every OOP language that I know of.)




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00   ` Spasmo
  1996-07-29  0:00     ` Thomas Kendelbacher
@ 1996-07-30  0:00     ` David Wheeler
  1996-07-31  0:00       ` Spasmo
  1996-07-30  0:00     ` Ken Garlington
  2 siblings, 1 reply; 46+ messages in thread
From: David Wheeler @ 1996-07-30  0:00 UTC (permalink / raw)



Spasmo (cosc19z5@Bayou.UH.EDU) wrote:


(C++ example)

: 	Person p;
: 	p.walk();
: 	p.talk();
: 	p.eat();

(Ada example, modified to use a "use" clause)

: begin
: 	Walk(P);
: 	Talk(P);
: 	Eat(P);
: end Main;

: Correct me if I'm wrong on this.  So you're still passing parameters
: which means that data and subprograms are still 2 different entities
: which sorta hurts the abstraction, rather than in say C++ where 
: you've got a unified object.   


I'm afraid you haven't got it.  Correction, per your request, follows :-).

In _BOTH_ C++ _AND_ Ada you pass a parameter.

In C++ you say:
   p.walk();
In Ada you say:
   walk(p);

IN BOTH CASES YOU PASS A PARAMETER.  BOTH. BOTH. BOTH.
When you say "p.walk()" in C++, "p" is the first parameter!

The only difference is that, to dispatch in C++, you
use a different syntax and the dispatching parameter is listed in
a distinguished position.  In C++ the parameter is always called "this".
In Ada, any parameter can be a dispatching parameter, and the
syntax for calling the method doesn't change.

C++ PASSES A PARAMETER.  It has to, otherwise how would the
C++ operation being called know which object to work with?

The different syntax seems to be really throwing you. Don't let it.
In fact, if in the Ada example P is of type "Person'Class", and
in C++ the operations are all virtual, the two examples above are
EXACTLY equivalent and will do EXACTLY the same thing.
They'll look at a pointer "hidden" in P to look up the correct
"walk" operation for this type, and then dispatch to it, passing
a pointer/access value to P as the first parameter.


: rather than a unified object that was like a combination of 
: data and subprograms that enabled it to smoothly simulate an
: entity?

Data and subprograms are unified, but Ada thinks of structuring in
terms of _packages_.  An Ada package with a tagged data structure 
and subprograms using it defines a unified object definition.

I think you're not understanding the key role of Ada packages.
Packages are the _primary_ Ada structuring mechanism.
In Ada, you can't "with" half a package.  When you "with" the
package, you "with" the whole thing, data structures AND operations.


: Also there's another slight difference -- inheritance.  From
: what I'm seeing, if we wanted to create say a SuperPersons
: package that inherited from persons we'd create a new package
: called SuperPerson, then we'd with the Persons package, and
: provide "wrappers" for everything defined in the Persons
: package right?

Wrong.  If that were true, you wouldn't have inheritance
the way most people define the term.  Children of tagged types
inherit all the operations of their ancestors.

:  Then we'd of course inherit from the data
: types and add in any new functionality that we wanted to,
: am I correct?

No, you inherit operations, too.  Of course, if you don't
override the operations in the child types, you get what was
defined by the parent.

: For example here's a crude idea of what I'm talking about:

: with Persons;
: package SuperPersons is

: 	type SuperPerson is tagged private;

: 		procedure Walk(SP : SuperPerson);
: 		procedure Talk(SP : SuperPerson);
: 		procedure Eat(SP : SuperPerson);

: 	private

: 	type SuperPerson is new Persons.Person with
: 		record
: 			SuperPowers : Power;
: 		end record;

: end SuperPersons;

: then all our procedures like Walk, Talk, Eat, etc... would need
: to call their predecessors right?  For instance:

Nope.  If you don't override Walk, for example, you'll get
the "Walk" operation defined by "Person".


: Am I correct or can we in fact inherit operations without manually
: providing wrappers for the predecessors?

You inherit without manually providing wrappers for the
predecessors.  That's one of the primary capabilities of Ada 95.

Still in doubt? Go to my example, program Small at
 "http://lglwww.epfl.ch/Ada/Tutorials/Lovelace/small.htm".

 Click on the package spec for Players -- gee, no operations defined!
 Where are they defined? Well, Player is a child of Creature, so click on
 that -- still no operations -- click on its parent, Occupant,
 and you'll see a whole bunch of operations (and more on its parent,
 Thing).  You get all the operations of your ancestors, and you
 DON'T have to define the wrappers.

 Want to see a trivial example of overriding? See Occupant's
 May_I_Get method and compare it to Item's May_I_Get method.
 The Get command simply calls May_I_Get, dispatching to whichever
 version is the correct one for the type.


IN SUMMARY:

 1. Both C++ and Ada pass parameters to do dispatching.
    They have to, otherwise you wouldn't know what you're working on.

 2. Packages are the key Ada structuring mechanism.

 3. Tagged type methods (aka primitive operations) inherit.


--- David A. Wheeler
Net address: wheeler@ida.org






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

* Re: Ada95 OOP Questions
  1996-07-29  0:00   ` David Wheeler
@ 1996-07-30  0:00     ` Spasmo
  1996-07-30  0:00     ` Spasmo
  1 sibling, 0 replies; 46+ messages in thread
From: Spasmo @ 1996-07-30  0:00 UTC (permalink / raw)



David Wheeler (wheeler@aphrodite.csed.ida.org) wrote:
: Andre Spiegel (spiegel@berlin.informatik.uni-stuttgart.de) wrote:
: : Spasmo writes:

[Snip]

: : With a use-clause, it looks better

: :     with Persons; use Persons;

: :     P : Person;

: :     Walk (P);
: :     Talk (P);
: :     Eat  (P);

Well since I try to avoid using a use-clause (I like the
namespace protection I get), the above really (to me) doesn't
look any better (not that the first one looked bad).  



: : > Correct me if I'm wrong on this.  So you're still passing parameters
: : > which means that data and subprograms are still 2 different entities
: : > which sorta hurts the abstraction, rather than in say C++ where 
: : > you've got a unified object.   

: : You _are_ wrong.  The subprograms actually _are_ a part of the object,
: : and they "go" with it, so to speak of, whereever you take the object.
: : It is just less obvious from the syntax in Ada.

Oh.


: Spiegel's right.  Spasmo - you're concentrating on minor syntactic variance.
: Ada treats all calls with the same syntax; C++'s syntax varies depending
: on how it's defined.  The difference is unimportant.

Well I can live with passing parameters but still the question
of inheriting operations from a parent class defined in a
different module is IMO a big deal.  I mean, I've looked at
the Lovelace tutorial and checked on this, even looked at the
OOP section in the "Core Language" section of the rationale 
(after a while I started skimming), but I've yet to see
this.  


: To see an example of OO in Ada95, look at my "Small" program at:
:   "http://lglwww.epfl.ch/Ada/Tutorials/Lovelace/small.htm"
: You'll see lots of OO concepts, and operations unified with the object.

Indeed, this is what I need to do.  I'm heading over there
right now and looking at the program.  I hope a good example
(Small is mentioned a lot) will be the thing to make me realize
just what it is I've been missing.


: --- David A. Wheeler
: Net address: dwheeler@ida.org


--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-07-29  0:00   ` David Wheeler
  1996-07-30  0:00     ` Spasmo
@ 1996-07-30  0:00     ` Spasmo
  1 sibling, 0 replies; 46+ messages in thread
From: Spasmo @ 1996-07-30  0:00 UTC (permalink / raw)



[I've read Small, and think I actually learned something :) so I'm
just posting here to check and also so no bandwidth is wasted
on trying to help me out if I've already gotten this]


David Wheeler (wheeler@aphrodite.csed.ida.org) wrote:
: Andre Spiegel (spiegel@berlin.informatik.uni-stuttgart.de) wrote:
: : Spasmo writes:

[Snip]

: : > Correct me if I'm wrong on this.  So you're still passing parameters
: : > which means that data and subprograms are still 2 different entities
: : > which sorta hurts the abstraction, rather than in say C++ where 
: : > you've got a unified object.   

: : You _are_ wrong.  The subprograms actually _are_ a part of the object,
: : and they "go" with it, so to speak of, whereever you take the object.
: : It is just less obvious from the syntax in Ada.

I took your advice and looked at some of the OO parts of your
"Small" program (Thing and its children), and I think I
understand things now.  In any case I'm going to go back
and check out "Small" again, it looks like a cool program
and studying it can teach me some valuable stuff!

Here are things as I understand them (correct me if I'm wrong).

I did a very simple parent class and a function accepting that
parent class as an argument in a package.

In another package I declared another class that inherited from
the parent class but did nothing else.  This package of course
with'ed the parent package.

I then wrote a program that with'ed the child package and called
a function that wasn't defined in the child class, but in
the parent class and it went through fine.

What I'm concluding from this is that the functions are inherited
and for this to happen a few things need to be met:
	1) The package defining the parent class has to be visible
	2) The package that with's the parent class declares a
	   child class.
	3) Any functions inherited are functions that take the
	   parent class as an argument.

So what it is is that a subprogram really does belong to a class,
but the way we mark a subprogram as being a member of a class
is if it accepts that class as one of its parameters right?  So
we're still passing objects to subprograms but inheritance,
etc... are in fact performed, it's just the arguments that
"tag" (loose use of this term) a subprogram as a class method
and imply inheritance into other packages.

If I'm incorrect on any of this or if anyone wants to add in
I'm all ears.  I hope I got it right because it's starting
to make sense :)



: Spiegel's right.  Spasmo - you're concentrating on minor syntactic variance.
: Ada treats all calls with the same syntax; C++'s syntax varies depending
: on how it's defined.  The difference is unimportant.

Well this variance had me genuinely confused so I didn't see the
true nature of OOP in Ada95.


: To see an example of OO in Ada95, look at my "Small" program at:
:   "http://lglwww.epfl.ch/Ada/Tutorials/Lovelace/small.htm"
: You'll see lots of OO concepts, and operations unified with the object.

Yep I looked at your "Small" program and if what I said above
is on the mark, then it's finally gotten me to realize what
you poor folks have been trying to drive into my thick skull.


: --- David A. Wheeler
: Net address: dwheeler@ida.org


--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-07-29  0:00     ` Thomas Kendelbacher
@ 1996-07-31  0:00       ` Spasmo
  1996-08-01  0:00         ` Thomas Kendelbacher
  1996-08-02  0:00         ` Gene Ouye
  1996-08-01  0:00       ` Jon S Anthony
  1 sibling, 2 replies; 46+ messages in thread
From: Spasmo @ 1996-07-31  0:00 UTC (permalink / raw)



Thomas Kendelbacher (Thomas.Kendelbacher@erno.de) wrote:
: In article <4tgi88$5fi@Masala.CC.UH.EDU>, cosc19z5@Bayou.UH.EDU (Spasmo) writes:

[Snip]

: >Correct me if I'm wrong on this.  So you're still passing parameters
: >which means that data and subprograms are still 2 different entities
: >which sorta hurts the abstraction, rather than in say C++ where 
: >you've got a unified object.   

: See it from this point of view: It's just a different syntax for the
: same thing ("p.walk()" vs. "Walk(P)"), and putting the object P in front
: is just some syntactic sugar in C++ which is translated basically to the
: same code - a reference to the object is passed to the function as its
: first parameter.

Point well taken, I guess I've just had my view clouded by
other OO languages.  This and my confusion about inheritance
led to the above question.



: >That's pretty much what I was talking about.  I'm not saying that
: >one is necessarily worse than the other, I was just wondering if
: >there was a rationale for doing it that particular way in Ada
: >rather than a unified object that was like a combination of 
: >data and subprograms that enabled it to smoothly simulate an
: >entity?

: The Ada way of writing this comes from the tradition of "abstract data
: types," where a type is defined by the operations declared on it.
: So, there's definitely a conceptual connection between data and subprograms.

Ok gotcha.  In any case after thinking carefully I do
see the whole view, it's just that to me a total 
merger of data and operations seemed to be a cornerstone
of OOP (that's just the way I was using it), so I really
had a hard time seeing where the inheritance actually
kicked in.


: >Also there's another slight difference -- inheritance.  From
: >what I'm seeing, if we wanted to create say a SuperPersons
: >package that inherited from persons we'd create a new package
: >called SuperPerson, then we'd with the Persons package, and
: >provide "wrappers" for everything defined in the Persons
: >package right?  Then we'd of course inherit from the data
: >types and add in any new functionality that we wanted to,
: >am I correct?
: >
: > [.. example recoding the Persons operations for a derived type ..]
: >
: >Am I correct or can we in fact inherit operations without manually
: >providing wrappers for the predecessors?

: The latter is true: Even back in Ada 83, a derived type automatically
: inherited all operations declared with the original type (in line with
: the view of a type as "abstract data type"; the derived type would be
: meaningless without the operations!)  This was of course preserved
: by Ada 95; the difference is that Ada 95 now has tagged types, while
: Ada 83 derived types were always incompatible with their parent types
: (save by explicit conversion), and data extension was not directly
: supported.

Gotcha.  So if I declare any type, tagged or not, then operations
will be inherited and I can refer to them in "child packages"?
This would mean that "inheritance" is pretty consistent regardless
of OO extensions or not eh?


: >Well what I learned in C++ was that "class" referred to the declaration/
: >definition, whereas an object is an instance of a class.  So using
: >my old example, Person is a class, but p is an object since it's an
: >instance of Person.  Still that is kinda moot since we're more concerned
: >with Ada rather than C++.  I'll look at Question 5.1 again (I skimmed
: >over certain parts of the FAQ last time I read it which was when
: >I was trying to find out more about Ada to see whether or not I'd
: >want to program in it).

: What's the big difference here? The type corresponds to the class, as it defines
: public/private data and operations, and each value of the type (e.g. stored in a
: variable) corresponds to an instance. It's not so much different from your C++
: example: You wrote that in a C++ statement like "p.walk()", p "is" a Person
: object; but to be exact, it is but a _name_ for the actual object (a variable,
: just like in Ada.)

Well once again it's just that I was used to one particular way
of doing things which sorta locked me into seeing that as *THE*
way.  Ignorant of me I agree.  The biggest leap was actually
in the realization that the parameter could influence inheritance
which took a while to sink in since it was just a new concept
to me.


: There is an essential difference between objects in C++ and Ada, though; in Ada,
: you can't test for object identity as easily, like writing "this == that" in C++
: (except if you explicitly switch to access types.) This can be a nuisance if
: you're used to OO languages which support object identity directly, like C++ or
: Smalltalk.

Well the equality operations are defined for all types
so isn't it just a matter of saying if this = that
in Ada?


[Snip]

Thanks for the assistance.




: -- 
: Thomas Kendelbacher   |   email : Thomas.Kendelbacher@erno.de
: DASA RI / Abt. RIT14  |   voice : +49 421 539 5492 (working hours)
: Postfach 28 61 56     |      or : +49 421 57 04 37 (any other time)
: D-28361 Bremen        |     fax : +49 421 539 4529 (any time)
: Germany



--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-07-30  0:00     ` David Wheeler
@ 1996-07-31  0:00       ` Spasmo
  0 siblings, 0 replies; 46+ messages in thread
From: Spasmo @ 1996-07-31  0:00 UTC (permalink / raw)



David Wheeler (wheeler@aphrodite.csed.ida.org) wrote:
: Spasmo (cosc19z5@Bayou.UH.EDU) wrote:

[Snip]

: : Correct me if I'm wrong on this.  So you're still passing parameters
: : which means that data and subprograms are still 2 different entities
: : which sorta hurts the abstraction, rather than in say C++ where 
: : you've got a unified object.   


: I'm afraid you haven't got it.  Correction, per your request, follows :-).

: In _BOTH_ C++ _AND_ Ada you pass a parameter.

: In C++ you say:
:    p.walk();
: In Ada you say:
:    walk(p);

: IN BOTH CASES YOU PASS A PARAMETER.  BOTH. BOTH. BOTH.
: When you say "p.walk()" in C++, "p" is the first parameter!

*Nod*.  It was the syntax that was throwing me for a loop.
I saw things done a particular way and immediately thought
it to be "THE" way.  My mistake.


: The only difference is that, to dispatch in C++, you
: use a different syntax and the dispatching parameter is listed in
: a distinguished position.  In C++ the parameter is always called "this".
: In Ada, any parameter can be a dispatching parameter, and the
: syntax for calling the method doesn't change.

: C++ PASSES A PARAMETER.  It has to, otherwise how would the
: C++ operation being called know which object to work with?

Right.



[Snip]


: : Am I correct or can we in fact inherit operations without manually
: : providing wrappers for the predecessors?

: You inherit without manually providing wrappers for the
: predecessors.  That's one of the primary capabilities of Ada 95.

: Still in doubt? Go to my example, program Small at
:  "http://lglwww.epfl.ch/Ada/Tutorials/Lovelace/small.htm".

Actually it was your program "Small" that showed me the
light so to speak.  I wrote some "quick and dirty" code
and realized that the children do inherit the operations
so we can access parent operations via the children without
doing anything.  It was just the thought of the parameters
influencing inheritance that threw me again.



:  Click on the package spec for Players -- gee, no operations defined!
:  Where are they defined? Well, Player is a child of Creature, so click on
:  that -- still no operations -- click on its parent, Occupant,
:  and you'll see a whole bunch of operations (and more on its parent,
:  Thing).  You get all the operations of your ancestors, and you
:  DON'T have to define the wrappers.

:  Want to see a trivial example of overriding? See Occupant's
:  May_I_Get method and compare it to Item's May_I_Get method.
:  The Get command simply calls May_I_Get, dispatching to whichever
:  version is the correct one for the type.

Overriding is no problem.  I pretty much have an idea at
this point as to what's going on.



: IN SUMMARY:

:  1. Both C++ and Ada pass parameters to do dispatching.
:     They have to, otherwise you wouldn't know what you're working on.

:  2. Packages are the key Ada structuring mechanism.

:  3. Tagged type methods (aka primitive operations) inherit.


Thanks a ton for clearing this up!



: --- David A. Wheeler
: Net address: wheeler@ida.org



--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-07-31  0:00       ` Spasmo
@ 1996-08-01  0:00         ` Thomas Kendelbacher
  1996-08-02  0:00         ` Gene Ouye
  1 sibling, 0 replies; 46+ messages in thread
From: Thomas Kendelbacher @ 1996-08-01  0:00 UTC (permalink / raw)



In article <4tor2u$ksg@Masala.CC.UH.EDU>, cosc19z5@Bayou.UH.EDU (Spasmo) writes:
>Gotcha.  So if I declare any type, tagged or not, then operations
>will be inherited and I can refer to them in "child packages"?
>This would mean that "inheritance" is pretty consistent regardless
>of OO extensions or not eh?

Right.

>: There is an essential difference between objects in C++ and Ada, though; in Ada,
>: you can't test for object identity as easily, like writing "this == that" in C++
>: (except if you explicitly switch to access types.) This can be a nuisance if
>: you're used to OO languages which support object identity directly, like C++ or
>: Smalltalk.
>
>Well the equality operations are defined for all types
>so isn't it just a matter of saying if this = that
>in Ada?

No. The standard Ada "=" would just compare the contents of the records (if they
are not limited), so two Persons with equal attributes would be considered the
same person (that's equivalence, in contrast to object identity.)
In C++/Smalltalk, you effectively compare pointers, so two Persons with the same
name and birthday *won't* be merged into siamese twins...
(Remember, in C++ "this" for a class X is declared implicitly as "X* const this"
resp. "const X* const this", depending on the context.)

Of course, you can have the same in Ada, if you use access types explicitly.
In C++ (with the "this" pointer) you get this implicitly, and in Smalltalk
every (non-numeric) object is unique by using object "handles" (references)
uniformly for each and everything. (In fact, in Smalltalk you have two different
operators, "=" testing for equivalence and "==" testing for object identity.)

-- 
Thomas Kendelbacher   |   email : Thomas.Kendelbacher@erno.de
DASA RI / Abt. RIT14  |   voice : +49 421 539 5492 (working hours)
Postfach 28 61 56     |      or : +49 421 57 04 37 (any other time)
D-28361 Bremen        |     fax : +49 421 539 4529 (any time)
Germany






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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (5 preceding siblings ...)
  1996-07-30  0:00 ` Robert I. Eachus
@ 1996-08-01  0:00 ` Jon S Anthony
  1996-08-13  0:00 ` Eric C. Newton
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Jon S Anthony @ 1996-08-01  0:00 UTC (permalink / raw)



In article <4toref$ksg@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

> : IN BOTH CASES YOU PASS A PARAMETER.  BOTH. BOTH. BOTH.
> : When you say "p.walk()" in C++, "p" is the first parameter!
> 
> *Nod*.  It was the syntax that was throwing me for a loop.
> I saw things done a particular way and immediately thought
> it to be "THE" way.  My mistake.

Most people get this wrong unless they are coming from CLOS or Dylan or
some such where the Ada notation is the one used.

David writes:
> : IN SUMMARY:
> 
> :  1. Both C++ and Ada pass parameters to do dispatching.
> :     They have to, otherwise you wouldn't know what you're working on.

They have to because that is the way they are designed.  They do not
have per object methods like some OOLs...


> :  3. Tagged type methods (aka primitive operations) inherit.

Tagged type methods are a _proper_ subset of primitive operations, they
are not the same thing.  All primitive operations are inherited.

/Jon

-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

* Re: Ada95 OOP Questions
  1996-07-29  0:00     ` Thomas Kendelbacher
  1996-07-31  0:00       ` Spasmo
@ 1996-08-01  0:00       ` Jon S Anthony
  1 sibling, 0 replies; 46+ messages in thread
From: Jon S Anthony @ 1996-08-01  0:00 UTC (permalink / raw)



In article <4tor2u$ksg@Masala.CC.UH.EDU> cosc19z5@Bayou.UH.EDU (Spasmo) writes:

> Gotcha.  So if I declare any type, tagged or not, then operations
> will be inherited and I can refer to them in "child packages"?
> This would mean that "inheritance" is pretty consistent regardless
> of OO extensions or not eh?

Basically, yes.  But note that this is only true of _primitive_ operations.
These can only be user defined if the type is declared in a _package spec._
and the operations are declared there along with it.  If you declare the
type anywhere else, the operations you provide (even if they are in the
same immediate scope) are not primitive and will not be inherited:

procedure P is
   type T is ...
   function F ( X : T ) return ... -- NOT primitive op of T

   type T2 is new T ...            -- F is NOT inherited
...
end P;

package body B is
   type T is ...
   function F ( X : T ) return...  -- NOT primitive op of T

   type T2 is new T ...            -- F is NOT inherited
...
end B;

package C is
   type T is ...                   -- Defined in Pkg Spec. C
   function F ( X : T ) return...  -- F IS primitive op of T

   type T2 is new T ...            -- F IS inherited
end C;

package C.D is
   type T3 is new T2...            -- F IS inherited
...
end C.D;


> : There is an essential difference between objects in C++ and Ada,
> : though; in Ada, you can't test for object identity as easily, like
> : writing "this == that" in C++ (except if you explicitly switch to
> : access types.) This can be a nuisance if you're used to OO languages
> : which support object identity directly, like C++ or Smalltalk.
> : 
> 
> Well the equality operations are defined for all types
> so isn't it just a matter of saying if this = that
> in Ada?

Typically no.  In general, this will provide value semantic _equality_
not _identity_, i.e., this and that have the same _value_ but are two
different objects.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

* Re: Ada95 OOP Questions
  1996-07-31  0:00       ` Spasmo
  1996-08-01  0:00         ` Thomas Kendelbacher
@ 1996-08-02  0:00         ` Gene Ouye
  1 sibling, 0 replies; 46+ messages in thread
From: Gene Ouye @ 1996-08-02  0:00 UTC (permalink / raw)



Spasmo wrote:
> 
> Thomas Kendelbacher (Thomas.Kendelbacher@erno.de) wrote:
> : In article <4tgi88$5fi@Masala.CC.UH.EDU>, cosc19z5@Bayou.UH.EDU (Spasmo) writes:

 [much deletia...]

> : The latter is true: Even back in Ada 83, a derived type automatically
> : inherited all operations declared with the original type (in line with
> : the view of a type as "abstract data type"; the derived type would be
> : meaningless without the operations!)  This was of course preserved
> : by Ada 95; the difference is that Ada 95 now has tagged types, while
> : Ada 83 derived types were always incompatible with their parent types
> : (save by explicit conversion), and data extension was not directly
> : supported.
> 
> Gotcha.  So if I declare any type, tagged or not, then operations
> will be inherited and I can refer to them in "child packages"?
> This would mean that "inheritance" is pretty consistent regardless
> of OO extensions or not eh?
> 

Well, yes and no.  If your notion of inheritance implies polymorphism, aka 
dynamic dispatching, then no.  If you derive any type, you'll get the 
operations and the structure of the type, ie, the "record components" (or 
"data members" in other worlds ;-) but you won't get dynamic dispatching 
unless you're deriving from something that keeps some sort of type id that 
can be used at runtime, thus the "tag" of tagged records.

So, if you want polymorphism with your inheritance, you have to derive from 
tagged types.  There are other issues as well, but this is the biggest 
difference that most people notice when they come from other OOPLs.




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

* Re: Ada95 OOP Questions
  1996-07-29  0:00   ` Thomas Kendelbacher
@ 1996-08-02  0:00     ` Robert Dewar
  1996-08-05  0:00       ` Thomas Kendelbacher
  0 siblings, 1 reply; 46+ messages in thread
From: Robert Dewar @ 1996-08-02  0:00 UTC (permalink / raw)



Thomas said

"No, it doesn't look better, at least to me.
(OK, this is a 5-liner; consider a 'real' program.)

Having been working on large-scale Ada projects for years, I have learned
to avoid the use of use as much as possible."

This seems an inappropriate knee-jerk reaction to use. Thomas did you
read the thread on the issue of use and dispatching calls. Remember that
your experience on "large scale Ada projects" has been based on a  totaly
different environment than we are talking about now, namely one in which
no dynamic dispatching occurs.

Generally in Ada 83, people like to avoid use so that when they see
Pkg.xyz they know that they can find the routine that will be called
in Pkg (the spec in the spec of Pkg and the code in the body).

The trouble is that with a dispatching call, you write Pkg.xyz and it
does NOT mean that the code is in Pkg -- as Laurent noted, it does
mean the relevant spec is in the spec of Pkg, but the whole point of
dispatching is to make sure that at compile time you have no idea
where the code that will actually be called resides, indeed the code
may be in a unit that has not been written yet.

A number of people find that confusing, and so are willing to onsider
using "use" for the dispatching case.

You may or may not agree, but it is certain that your previous Ada 83
experience is not a useful guide here.





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

* Re: Ada95 OOP Questions
  1996-07-30  0:00     ` Ken Garlington
@ 1996-08-04  0:00       ` Spasmo
  0 siblings, 0 replies; 46+ messages in thread
From: Spasmo @ 1996-08-04  0:00 UTC (permalink / raw)



Ken Garlington (garlingtonke@lmtas.lmco.com) wrote:
: Spasmo wrote:

[Snip]

: Depends on what you're abstrating. If you don't want an abstract data type,
: but you want a generic abstract data object, why not do this:

:   generic
:   package Person is

:     procedure Walk;
:     procedure Talk;
:     procedure Eat;

:   private

:     type Person_Type is -- as before
:     Object : Person_Type;

:   end Person;

: Translating your C++ code:

:    package P is new Person;  -- Person p;
:    P.Walk;                   -- p.walk();
:    P.Talk;                   -- p.talk();
:    P.Eat;                    -- p.eat();

: Note, however, that there are things you can't do with a GADO (like
: make an array of Persons) that you can do with an ADT.

Yeah that's something I fiddled with initially but realized
that it just didn't work with arrays and the like.  Sure I
could arbitrarily create as many instances of the above package
as I liked (via new packages) but I couldn't use arrays, linked
lists of them, etc...



: If your complaint is that you like p.eat() better than eat(p), on the
: other hand, then I don't see this as an abstraction difference - just
: a syntax difference.

Right it was the syntax that got to me -- and I came to grips
with that :).


: Just out of curiousity, if Person is declared in the C++ equivalent of
: a package (and I forget the nomenclature -- space?), what does your C++
: code look like?

Well when I used C++, things like namespaces, RTTI (standardized?)
and even exception handling weren't universally implemented so
in all reality these classes were taking up the global name space.



: -- 
: LMTAS - "Our Brand Means Quality"

--
Spasmo
"Everyone has secrets, but sometimes you get caught,
 So if it's just between us, my silence can be bought"
	"Blackmail" by Sloppy Seconds





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

* Re: Ada95 OOP Questions
  1996-08-02  0:00     ` Robert Dewar
@ 1996-08-05  0:00       ` Thomas Kendelbacher
  1996-08-06  0:00         ` Robert Dewar
                           ` (2 more replies)
  0 siblings, 3 replies; 46+ messages in thread
From: Thomas Kendelbacher @ 1996-08-05  0:00 UTC (permalink / raw)



In article <dewar.838959126@schonberg>, dewar@cs.nyu.edu (Robert Dewar) writes:
>Generally in Ada 83, people like to avoid use so that when they see
>Pkg.xyz they know that they can find the routine that will be called
>in Pkg (the spec in the spec of Pkg and the code in the body).
>
>The trouble is that with a dispatching call, you write Pkg.xyz and it
>does NOT mean that the code is in Pkg -- as Laurent noted, it does
>mean the relevant spec is in the spec of Pkg, but the whole point of
>dispatching is to make sure that at compile time you have no idea
>where the code that will actually be called resides, indeed the code
>may be in a unit that has not been written yet.
>
>A number of people find that confusing, and so are willing to onsider
>using "use" for the dispatching case.
>
>You may or may not agree, but it is certain that your previous Ada 83
>experience is not a useful guide here.

No, I don't agree at all. Sorry if there has been a thread on this before,
I have missed it, but I don't want to restart it either.

Just one sentence (or two :-):

When grep is your only tool to find out where a procedure FOO_BAR is defined,
then this IS a maintenance nightmare, especially for anyone who is not the
original author. You're right, my experience which leads me to avoid using use
comes from Ada 83, of course (how many large-scale Ada 95 systems are there?),
but the argument is still valid!

If the introduction of dispatching calls leads people to produce less
maintainable code, then this is a *bad* *thing*. (By the way, I don't think
it's confusing that the qualifier is the spec where the type is defined;
rather, it's a good starting point to narrow down the search for the real
code. Using use here leaves you with no clue at all! And this "confusing"
point is not peculiar to dispatching calls: it occurs with Ada 83 derived
types as well. Not new, although the "search direction" is reversed in that
case.)

Just my 2p.

-- 
Thomas Kendelbacher   |   email : Thomas.Kendelbacher@erno.de
DASA RI / Abt. RIT14  |   voice : +49 421 539 5492 (working hours)
Postfach 28 61 56     |      or : +49 421 57 04 37 (any other time)
D-28361 Bremen        |     fax : +49 421 539 4529 (any time)
Germany






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

* Re: Ada95 OOP Questions
  1996-08-06  0:00         ` Robert Dewar
@ 1996-08-06  0:00           ` Thomas Kendelbacher
  1996-08-06  0:00             ` Robert A Duff
  1996-08-12  0:00             ` Robert I. Eachus
  1996-08-08  0:00           ` Theodore E. Dennison
  1 sibling, 2 replies; 46+ messages in thread
From: Thomas Kendelbacher @ 1996-08-06  0:00 UTC (permalink / raw)



In article <dewar.839329517@schonberg>, dewar@cs.nyu.edu (Robert Dewar) writes:
>So grep will not be enough, even if you ban USE. Really you need decent
>tools to build Ada programs, and relying on grep for locating defining
>occurrences of subprogram references is pretty miserable (note for 
>example that it fails in any case in the overloaded case). It is hard
>for me to believe that there are Ada environments with no better 
>capabilities than grep for finding things.

Sadly, I must say that this seems to be the state-of-the-art in the European
space industry.

>With GNAT, you have two possibilities. For static analysis, you can use
>gnatf, and then if you like, use the emacs interface to get straight from
>applied to defining occurrences. (note that soon we will integrate gnatf
>with gnat1 making this possibility a bit more convenient).

Fine, if GNAT can do all this; unfortunately, we aren't allowed to use GNAT
because it's --ahem-- too cheap, you see...  :-)

The really expensive Ada systems which are being used here are not very helpful,
especially w.r.t. interactive development support (there is none.)

Of course I could have the Ada system generate a 20-page cross reference listing;
is that what you mean? ;-)

>It is interesting though to see a very clear statement that the motivation 
>for banning use clauses is entirely tool driven in this case, or rather
>we should say driven by lack of tools. It is interesting to wonder how
>the use of USE clauses would be affected by good tools.

I'm not advocating a ban on use clauses at all; indeed, I do use use myself
quite often, especially for the typical case of certain base packages
which are "with"ed everywhere in a certain project (you mentioned examples
from GNAT itself.)  But generally, I prefer to put use statements not
immediately after a "with" before a 1000 lines package body, but into those
procedures which do use the imported unit. IMHO, this helps identifying
actual dependencies between units.
(OK, again you may say that this is not really a point if you have the
right tools. I whole-heartedly agree! It's just that I DON'T have them.)

>As in all style matters, I don't like absolute rules,

--neither do I!--

>and for sure it is
>annoying to see programs use units that have been designed for use without
>USE and insisting on not using the USE, giving us highly useful names
>like Posix.Posix_Error :-)

Agreed, but POSIX was obviously NOT designed for use without USE!

Otherwise, POSIX.POSIX_ERROR would be POSIX.ERROR, which I would still find
more helpful than "use POSIX; [...] POSIX_ERROR [...]".

-- 
Thomas Kendelbacher   |   email : Thomas.Kendelbacher@erno.de
DASA RI / Abt. RIT14  |   voice : +49 421 539 5492 (working hours)
Postfach 28 61 56     |      or : +49 421 57 04 37 (any other time)
D-28361 Bremen        |     fax : +49 421 539 4529 (any time)
Germany






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

* Re: Ada95 OOP Questions
  1996-08-06  0:00           ` Thomas Kendelbacher
@ 1996-08-06  0:00             ` Robert A Duff
  1996-08-07  0:00               ` Robert Dewar
  1996-08-12  0:00             ` Robert I. Eachus
  1 sibling, 1 reply; 46+ messages in thread
From: Robert A Duff @ 1996-08-06  0:00 UTC (permalink / raw)



In article <4u7h1r$jrn@mailsrv2.erno.de>,
Thomas Kendelbacher <Thomas.Kendelbacher@erno.de> wrote:
>I'm not advocating a ban on use clauses at all; indeed, I do use use myself
>quite often, especially for the typical case of certain base packages
>which are "with"ed everywhere in a certain project (you mentioned examples
>from GNAT itself.) ...

A useful thing to do is:

Suppose you have 17 packages that are with-ed pretty much everywhere.
Do you put 17 with-clauses on every package?  Not very readable, IMHO,
since the reader's eyes tend to glaze over with all those with_clauses,
since they're all more-or-less the same.  Instead, you can make an empty
library package, and put the 17 with's on it, and make the rest of your
software children of that empty parent.

Of course, in doing that, you require the reader to memorize all 17 of
those packages, which you shouldn't do unless they really are globally
used all over the place.  Maybe 17 is a bit high...

>>As in all style matters, I don't like absolute rules,
>
>--neither do I!--

Nor me.  But since we haven't defined what "style" means, this is pretty
meaningless.  There are some rules in the RM that could be considered
"style rules", and yet they are absolute -- the compiler will complain
if you violate them.

An absolute rule like "never use unchecked conversions" is bad.  But an
absolute rule like "never use unchecked conversions without saying so"
is good (and that's what the RM says, since it requires a "with
Unchecked_Conversion;" at the top).  Both rules are absolute, but one is
good and one is bad.  Of course another good rule is, "Don't use
unchecked conversions unless necessary", but the RM doesn't say that,
since it's a matter of opinion.

- Bob




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

* Re: Ada95 OOP Questions
  1996-08-05  0:00       ` Thomas Kendelbacher
  1996-08-06  0:00         ` Robert Dewar
@ 1996-08-06  0:00         ` Robert I. Eachus
  1996-08-10  0:00         ` Chris Morgan
  2 siblings, 0 replies; 46+ messages in thread
From: Robert I. Eachus @ 1996-08-06  0:00 UTC (permalink / raw)



In article <4u4ln3$fur@mailsrv2.erno.de> Thomas.Kendelbacher@erno.de (Thomas Kendelbacher) writes:

  > If the introduction of dispatching calls leads people to produce
  > less maintainable code, then this is a *bad* *thing*. (By the way,
  > I don't think it's confusing that the qualifier is the spec where
  > the type is defined; rather, it's a good starting point to narrow
  > down the search for the real code. Using use here leaves you with
  > no clue at all! And this "confusing" point is not peculiar to
  > dispatching calls: it occurs with Ada 83 derived types as
  > well. Not new, although the "search direction" is reversed in that
  > case.)

    Here, here!  Fortunately, it is possible to write large portions
of systems in Ada 95 without using dynamic dispatching.  I am a strong
advocate of the added support for polymorphism in Ada 95, but I also
understand that in real systems you want to restrict the use of 'CLASS
to very well defined parts of the system.  Often these portions are
the high level glue which ties the system together, and some are very
low level routines where redispatching must be done carefully. (Is
'CLASS more or less of a "here be dragons" flag than "with System" or
"with Unchecked_Conversion"?  Don't know, but I'll look for all of
them, as well as "with Starlet", and "with Unchecked_Deallocation.")


--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




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

* Re: Ada95 OOP Questions
  1996-08-05  0:00       ` Thomas Kendelbacher
@ 1996-08-06  0:00         ` Robert Dewar
  1996-08-06  0:00           ` Thomas Kendelbacher
  1996-08-08  0:00           ` Theodore E. Dennison
  1996-08-06  0:00         ` Robert I. Eachus
  1996-08-10  0:00         ` Chris Morgan
  2 siblings, 2 replies; 46+ messages in thread
From: Robert Dewar @ 1996-08-06  0:00 UTC (permalink / raw)




Thomas said

"code. Using use here leaves you with no clue at all! And this "confusing"
point is not peculiar to dispatching calls: it occurs with Ada 83 derived
types as well. Not new, although the "search direction" is reversed in that
case.)"



Actually derived types are a little more problematical than that for the
"i never use use, all I have is grep" crowd.

If you forbid the use of USE you can still find a procedure call in 
your program

   xyz (a,b,c)

where xyz is nowhere in sight, it is not in the unit where the call occurs,
and it is not in any of the directly with'ed units. This happens if you
derive a type from say an exported subtype, you derive all the primitive
operations, and they are directly visible locally.

So grep will not be enough, even if you ban USE. Really you need decent
tools to build Ada programs, and relying on grep for locating defining
occurrences of subprogram references is pretty miserable (note for 
example that it fails in any case in the overloaded case). It is hard
for me to believe that there are Ada environments with no better 
capabilities than grep for finding things.

With GNAT, you have two possibilities. For static analysis, you can use
gnatf, and then if you like, use the emacs interface to get straight from
applied to defining occurrences. (note that soon we will integrate gnatf
with gnat1 making this possibility a bit more convenient).

Second, you can follow the call with gdb, which has the advantage of 
course of being a dynamic trace that follows dispatching calls. GDB will
then point right at the appropriate source location.

As to whether using dynamic dispatching makes programs less maintainable,
we do not have enough experience to know. There are isolated anecdotal
discussions on each side (one entertaining one was that the green design
team very specifically avoided introducing dynamic dispatching because they
had used Simula-67 extensively, and found exactly that large complex
Simula-67 programs were hard to maintain -- but that's just one
experience point, with one kind of application). Like any other feature,
there is a wide range from good-use to ab-use and it remains to be seen
where on this range typical OO applications will sit when the entire
life-cycle costs for large projects are considered.

It is interesting though to see a very clear statement that the motivation 
for banning use clauses is entirely tool driven in this case, or rather
we should say driven by lack of tools. It is interesting to wonder how
the use of USE clauses would be affected by good tools.

My preference is to write code that is unambiguous without any use of
qualification, i.e. to avoid reusing the same names in different packages,
because I think that is potentially confusing anyway. Then the code you
write can always be displayed with dots if you prefer dots -- dotted code
cannot necessarily be converted to non-dotted form.

Two tools would be useful in a compiler, both are on the thought list for
possible GNAT additions.

1. An option to ensure that even though you use dots, your references
would be unambiguous without them.

2. a dotifier tool

Of course I realize that if you are a confirmed anti-use person, then you
choose names differently, but I still find the package names and dots to
have a rather high noise-to-signal ratio when reading code.

A lot dpeends on the program. For example in GNAT, where generally you need
to be reasonably familiar with the structure of the front end to read the
code anyway, the compiler itself is written using USE, and you quickly
learn where things are (for example Analyze_Object_Declaration is obviously
in Sem_Ch3, the package that handles chapter 3 semantics, and we really do
not need to write Sem_Ch3.Analyze_Object_Declaration). On the other hand,
the run time library, with its 569 separate source files, is a place where
it is useful to use qualification extensively. We never use USE in library
specs (this is actually enforced by the compiler to some degree), and use
them only some of the time in library bodies for units that are clearly
intimately related, or very familiar.

As in all style matters, I don't like absolute rules, and for sure it is
annoying to see programs use units that have been designed for use without
USE and insisting on not using the USE, giving us highly useful names
like Posix.Posix_Error :-)





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

* Re: Ada95 OOP Questions
  1996-08-06  0:00             ` Robert A Duff
@ 1996-08-07  0:00               ` Robert Dewar
  1996-08-08  0:00                 ` Robert A Duff
  0 siblings, 1 reply; 46+ messages in thread
From: Robert Dewar @ 1996-08-07  0:00 UTC (permalink / raw)



Robert Duff says

"Nor me.  But since we haven't defined what "style" means, this is pretty
meaningless.  There are some rules in the RM that could be considered
"style rules", and yet they are absolute -- the compiler will complain
if you violate them."


OK, sorry, I thought the definition was clear. To me style rules are rules
that are placed ON TOP of the language rules, so a language rule is not
by definition a style rule. To me if a style rule is arguably reasonable
as an absolute rule, rather than a guideline, it should have been an
enforced language rule -- of course this rule itself is more of a 
guideline :-)





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

* Re: Ada95 OOP Questions
  1996-08-06  0:00         ` Robert Dewar
  1996-08-06  0:00           ` Thomas Kendelbacher
@ 1996-08-08  0:00           ` Theodore E. Dennison
  1996-08-09  0:00             ` Robert Dewar
  1996-08-12  0:00             ` Joel VanLaven
  1 sibling, 2 replies; 46+ messages in thread
From: Theodore E. Dennison @ 1996-08-08  0:00 UTC (permalink / raw)



Robert Dewar wrote:
> 
> So grep will not be enough, even if you ban USE. Really you need decent
> tools to build Ada programs, and relying on grep for locating defining
> occurrences of subprogram references is pretty miserable (note for
> example that it fails in any case in the overloaded case). It is hard
> for me to believe that there are Ada environments with no better
> capabilities than grep for finding things.
> 

The only environment I have ever used that had anything better than grep
was DEC's LSE/SCA combination. (I THINK it was "SCA", its been a while).
SCA was painfully slow, even on multiprocessing VAXen. I tried it for two
weeks before giving up on it.(Which made me hardier than anyone else on the
project by about a week and a half). Apparently its no easy task to chase
down references, even for a multiprocessing computer and Ada 83. The
experience gave me a whole new respect for our "no use" coding policy.

> With GNAT, you have two possibilities. For static analysis, you can use
> gnatf, and then if you like, use the emacs interface to get straight from
> applied to defining occurrences. (note that soon we will integrate gnatf
> with gnat1 making this possibility a bit more convenient).

That sounds cool. It makes sense that the compiler (or something built off
of it) could do the most efficient and accurate job of chasing down 
references. But how useful is this? Is it fast enough to be more of a 
help than a hinderance? Does ANYONE do this? I take it you don't, since 
you don't use emacs.

--------------------------Different Issue-------------------------------------

> As in all style matters, I don't like absolute rules, and for sure it is
> annoying to see programs use units that have been designed for use without
> USE and insisting on not using the USE, giving us highly useful names
> like Posix.Posix_Error :-)

From my point of view, it is very annoying that folks like the Posix group
INSIST on naming things in a redundant manner. It is made worse by the fact 
that the naming indirectly encourages use of (arguably) unsafe "use" clauses.
What is wrong with "Posix.Error"? It reads the same as "Posix_Error", but
gives the maintainer more information about the object.


-- 
T.E.D.          
                |  Work - mailto:dennison@escmail.orl.mmc.com  |
                |  Home - mailto:dennison@iag.net              |
                |  URL  - http://www.iag.net/~dennison         |




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

* Re: Ada95 OOP Questions
  1996-08-07  0:00               ` Robert Dewar
@ 1996-08-08  0:00                 ` Robert A Duff
  1996-08-09  0:00                   ` Robert Dewar
  0 siblings, 1 reply; 46+ messages in thread
From: Robert A Duff @ 1996-08-08  0:00 UTC (permalink / raw)



In article <dewar.839457355@schonberg>, Robert Dewar <dewar@cs.nyu.edu> wrote:
>OK, sorry, I thought the definition was clear. To me style rules are rules
>that are placed ON TOP of the language rules, so a language rule is not
>by definition a style rule. To me if a style rule is arguably reasonable
>as an absolute rule, rather than a guideline, it should have been an
>enforced language rule ...

Agreed.  But the language designers can't think of everything, so it may
well be that there some rules that really should be absolute, and yet
didn't get into the language.  I can't think of any at the moment (in
the case of Ada 95).  ;-)

And there are certainly some rules that *are* in the language, which
ought to have been non-absolute style rules.  I can think of a few, but
I fear it would start another pointless argument to mention them.  ;-)

>... -- of course this rule itself is more of a 
>guideline :-)

Indeed.

- Bob




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

* Re: Ada95 OOP Questions
@ 1996-08-08  0:00 W. Wesley Groleau (Wes)
  0 siblings, 0 replies; 46+ messages in thread
From: W. Wesley Groleau (Wes) @ 1996-08-08  0:00 UTC (permalink / raw)



You also have a readability question with regard to the syntax you've
been discussing.  If  Fred is type (class) Person  and  Fido is Dog, then at
first glance what would be the "intuitive" output of the following?

   C++   -   Fred.bite(Fido)           Ada   -   Persons.Bite(Fred,Fido);

Is it  "Yelp!"  or  "You miserable mutt!"   ?    :-)
Not a very good example, but what I'm getting at is, if you're using
English words for your identifiers, then English word order can reinforce
or work against the meaning in either case.  In previous posts,

   C++      Fred.eat;                 Ada        Persons.Eat(Fred);

If these are equivalent, perhaps the Ada translation should be
                                      Persons.Eating_Should_Be(Fred);
:-)

Now set that foolishness aside.  Do you want to make your Ada look like
C++ ?  Without giving up arrays and linked lists?  Although they weren't
intended for this, protected types/objects can do it!  They can have
not only functions, but procedures and entries.

protected type Person is  -- maybe 'does' should be a synonym for 'is' :-)
  procedure Eat;
  procedure Sleep;
  procedure Work;
  -- is there more to life?
end Person;

type Crowd is array (Natural range <>) of Person;

-- I am sure the rest is obvious....

... and even Ada-83 could do it with task types, provided identifiers
    were carefully chosen.  Not that I would necessarily recommend it,
    but it may in some designs model the real world better than
    non-concurrent objects.



---------------------------------------------------------------------------
W. Wesley Groleau (Wes)                                Office: 219-429-4923
Hughes Defense Communications (MS 10-40)                 Home: 219-471-7206
Fort Wayne,  IN   46808                  (Unix): wwgrol@pseserv3.fw.hac.com
---------------------------------------------------------------------------




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

* Re: Ada95 OOP Questions
  1996-08-08  0:00           ` Theodore E. Dennison
@ 1996-08-09  0:00             ` Robert Dewar
  1996-08-12  0:00             ` Joel VanLaven
  1 sibling, 0 replies; 46+ messages in thread
From: Robert Dewar @ 1996-08-09  0:00 UTC (permalink / raw)



"That sounds cool. It makes sense that the compiler (or something built off
of it) could do the most efficient and accurate job of chasing down
references. But how useful is this? Is it fast enough to be more of a
help than a hinderance? Does ANYONE do this? I take it you don't, since
you don't use emacs."

Right, I don't use it, although I am learning EMACS now (part of my
conversion from OS/2 and EPM to Win 95 :-)

I think in practice that thisw feature (using GNATF to provide information
to EMACS) will be much more useful when GNATF is integrated into GNAT, so
that you just get in the habit of compiling with the appropriate cross
referencing option (this will slow down compilation, but machines are
getting faster all the time, and besides, we probably will save enough
from going to the fast version of the GNAT front end to easily pay for
the extra cost of the cross reference processing).





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

* Re: Ada95 OOP Questions
  1996-08-08  0:00                 ` Robert A Duff
@ 1996-08-09  0:00                   ` Robert Dewar
  0 siblings, 0 replies; 46+ messages in thread
From: Robert Dewar @ 1996-08-09  0:00 UTC (permalink / raw)



Bob Duff said

"Agreed.  But the language designers can't think of everything, so it may
well be that there some rules that really should be absolute, and yet
didn't get into the language.  I can't think of any at the moment (in
the case of Ada 95).  ;-)"


Yes, indeed, it is useful if people realize that whenever they feel like
imposing an absolute style rule, they are in fact commenting on the language
design, and declaring that some aspect of it was wrong. Now there is nothing
unreasonable about making such a conclusion, but you need to invest some
effort to understand why a feature is in the language. It was not put there
for idle amusement.

If you propose a style rule "never use feature X", then it is quite likely
the case that you are simply unaware of some important use of feature X.
For example, I have now seen several Ada environments in which the Ada
style rule is "never use unchecked conversion", and as a result, pieces
of the program are written in C which could perfectly well be written in
Ada. 





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

* Re: Ada95 OOP Questions
  1996-08-05  0:00       ` Thomas Kendelbacher
  1996-08-06  0:00         ` Robert Dewar
  1996-08-06  0:00         ` Robert I. Eachus
@ 1996-08-10  0:00         ` Chris Morgan
  2 siblings, 0 replies; 46+ messages in thread
From: Chris Morgan @ 1996-08-10  0:00 UTC (permalink / raw)



In article <dewar.839329517@schonberg> dewar@cs.nyu.edu (Robert Dewar) writes:

   It is hard
   for me to believe that there are Ada environments with no better 
   capabilities than grep for finding things.

You better believe it!

  Without being too specific, a company I used to work for delivered a
1.5 mloc Ada system that was built on VAXes using mostly edt or tpu as
the editor. We didn't even have grep but DCL search is better than
nothing. There were no tools to help you other than these and the
compiler itself (which was not DEC Ada unfortunately). We did have an
old version of DEC LSE for Ada but nobody used it due to various
problems. Not surprisingly use clauses were discouraged in all
deliverable code. In fact the mindset was so prevalent I would find
myself banning use clauses for text_io in my own code.

  Before anyone asks why I nobody bothered to add some PD software for
VAXes, this was a host environment where you weren't really supposed
to even have much in your login.com file, let alone special
software.

  [Oh and I also had a vt terminal only and sometimes could
only get at the target hardware by taking potluck on Saturday
afternoons if the other teams were not using it. Such is the lot of
the poor benighted embedded systems programmer. I digress..]

  Perhaps the response is "that is not an Ada environment". Quite :-)

  Anyway that was then and now I mix and match to suit choosing to use
use for some packages and not for others. There is a middle way of
better readability through renames and use type clauses. I'm still
experimenting with the balance. 

Chris

chris.morgan@baesema.co.uk




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

* Re: Ada95 OOP Questions
  1996-08-08  0:00           ` Theodore E. Dennison
  1996-08-09  0:00             ` Robert Dewar
@ 1996-08-12  0:00             ` Joel VanLaven
  1 sibling, 0 replies; 46+ messages in thread
From: Joel VanLaven @ 1996-08-12  0:00 UTC (permalink / raw)



Theodore E. Dennison (dennison@escmail.orl.mmc.com) wrote:
: Robert Dewar wrote:
: > 
: > So grep will not be enough, even if you ban USE. Really you need decent
: > tools to build Ada programs, and relying on grep for locating defining
: > occurrences of subprogram references is pretty miserable (note for
: > example that it fails in any case in the overloaded case). It is hard
: > for me to believe that there are Ada environments with no better
: > capabilities than grep for finding things.

: The only environment I have ever used that had anything better than grep
: was DEC's LSE/SCA combination. (I THINK it was "SCA", its been a while).
: SCA was painfully slow, even on multiprocessing VAXen. I tried it for two
: weeks before giving up on it.(Which made me hardier than anyone else on the
: project by about a week and a half). Apparently its no easy task to chase
: down references, even for a multiprocessing computer and Ada 83. The
: experience gave me a whole new respect for our "no use" coding policy.

: > With GNAT, you have two possibilities. For static analysis, you can use
: > gnatf, and then if you like, use the emacs interface to get straight from
: > applied to defining occurrences. (note that soon we will integrate gnatf
: > with gnat1 making this possibility a bit more convenient).

: That sounds cool. It makes sense that the compiler (or something built off
: of it) could do the most efficient and accurate job of chasing down 
: references. But how useful is this? Is it fast enough to be more of a 
: help than a hinderance? Does ANYONE do this? I take it you don't, since 
: you don't use emacs.

  I have to agree that the compiler should come with tools able to do 
your searching for you.  For our compiler we put this into the soure code
"browser."  The browser has access to most of the information that the
compiler produces (it keeps it in a library) so it is quite fast.  I
find it very useful, especially when dealing with someone else's code!
Without such tools at my disposal I think I might never work on large
projects at all... :)

-- Joel
-- 
-- Joel VanLaven





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

* Re: Ada95 OOP Questions
  1996-08-06  0:00           ` Thomas Kendelbacher
  1996-08-06  0:00             ` Robert A Duff
@ 1996-08-12  0:00             ` Robert I. Eachus
  1 sibling, 0 replies; 46+ messages in thread
From: Robert I. Eachus @ 1996-08-12  0:00 UTC (permalink / raw)



In article <dewar.839593114@schonberg> dewar@cs.nyu.edu (Robert Dewar) writes:

  > If you propose a style rule "never use feature X", then it is quite likely
  > the case that you are simply unaware of some important use of feature X.
  > For example, I have now seen several Ada environments in which the Ada
  > style rule is "never use unchecked conversion", and as a result, pieces
  > of the program are written in C which could perfectly well be written in
  > Ada. 

   Yes, Unchecked_Conversion is only needed in a very few places, but
if you are sending data down a serial pipe, you probably need to use
it.*  Similarly, the only place that gotos seem to be needed is for
implementing finite state machines.  But they are NECESSARY for
implementing finite state machines, so in they stay.

*Yes, I know that Ada 95 has 'READ and 'WRITE.  But if you have to
define your own read and write routines?  See 13.13.2(36-40).
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (6 preceding siblings ...)
  1996-08-01  0:00 ` Jon S Anthony
@ 1996-08-13  0:00 ` Eric C. Newton
  1996-08-14  0:00 ` Eric C. Newton
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Eric C. Newton @ 1996-08-13  0:00 UTC (permalink / raw)



In article <4tl235$a1v@news.ida.org> (David Wheeler) writes:

 < Lots of stuff comparing C++ and Ada object syntax deleted >

   The only difference is that, to dispatch in C++, you
   use a different syntax and the dispatching parameter is listed in
   a distinguished position.  In C++ the parameter is always called "this".
   In Ada, any parameter can be a dispatching parameter, and the
   syntax for calling the method doesn't change.

Lots of object-oriented languages support passing objects as
parameters, with one of those objects being "special".  For example,
the "first" argument is used for dispatch.  Modula 3 does this.
Python does as well.

<More stuff about C++ and Ada example code begin equivalent removed>

   : rather than a unified object that was like a combination of 
   : data and subprograms that enabled it to smoothly simulate an
   : entity?

   Data and subprograms are unified, but Ada thinks of structuring in
   terms of _packages_.  An Ada package with a tagged data structure 
   and subprograms using it defines a unified object definition.

   I think you're not understanding the key role of Ada packages.
   Packages are the _primary_ Ada structuring mechanism.
   In Ada, you can't "with" half a package.  When you "with" the
   package, you "with" the whole thing, data structures AND operations.

I do a lot of OO programming.  I like to learn new languages.  I even
kinda like Ada.  You're right, of course.  The only difference is
syntax.  But isn't that whole dispatch trickyness worth a bit of extra
syntax at the call site?  I have read many well argued articles by Ada
proponants convincing me that Ada takes the trouble to make many
things explicit.  It would seem reasonable to me that this would have
extended to something like dispatching.

To me,
	obj.method(arguments);

makes it pretty clear that "obj" will be used to dispatch.

When I originally read about Ada 95's support for polymorphism, I
thought that it *must* support multiple dispatch arguments.  That is,
if you can make any argument the "dispatcher", why not make more than
one argument the dispatcher (as in CLOS, or Cecil)?  For example,

	method(obj1, obj2);

would choose the correct method based on the run-time types of both
obj1 *and* obj2.  So I pulled down GNAT, coded up a test, and *slam*,
the compiler let me know in no uncertain terms that only one argument
could be used for dispatch.  So much for making silly assumptions.

Packages are good for structuring code.  Namespace control is
essential in large systems.  But objects are kinda handy abstractions
as well.  Relying on packages as the ONLY structuring mechanism makes
objects-as-abstractions a little more obscure because they don't
provide any structure by themselves.  

It's a pretty hard sell to say (pardon the syntax, 8-):

	struct Person;
	Eat(Person);
	Walk(Person);
	Talk(Person);

"That's a person.  It has the features 'Eat, Walk, Talk'."

Vs.
	class Person
	{
		Eat();
	 	Walk();
		Talk();
	};

Yes, they are equivalent.  Yes, a quick search for 'Class will tell
you what functions dispatch on Person.  I'm sure an experienced OO
person will be able to handle it.  Anyone who can read C++ code can
certainly learn to mentally group functions based on the type argument
passed.  I wouldn't want to teach object oriented programming to
anyone with this syntax, though.  For example, the following would be
bad style, and impossible to do in C++ and Modula-3, but legal Ada 95,
right?

   package Matrixes is

	type Matrix is abstract new Limited_Controled with private;
	type Vector is abstract new Limited_Controled with private;
	type Matrix_Access is access all Matrix'Class;
	type Vector_Access is access all Vector'Class;

	-- Get a row from a matrix
	function Row(M : access Matrix'Class; r : Natural) 
		return Vector_Access;

	-- Get an element from a vector
	function Element(V: access Vector'Class; i : Natural)
		return Real;

	-- Get a column from a matrix
	function Column(M : access Matrix'Class; c : Natural) 
		return Vector_Access;

	-- ... more stuff ...
   end Matrixes;

<Misconceptions about Ada's support for OO programming deleted>

I keep trying to see packages like I see objects and it just doesn't
get any easier.  Namespaces are good.  Objects are good.  Yes, Ada 95
has both, but it is pretty good at hiding the objects.  Ada has such
nice explicit support for all kinds of other programming abstractions.
There are times, especially when programming in C, that I find that I
could really use the kind of tools available in Ada.  I just don't
find myself wishing I could make a procedure dispatch on a type by
adding a keyword.

-Eric
-- 
Eric C. Newton        Software Reuser.
Newton Consulting     Look at all the code I didn't write today!
ecn@clark.net	      http://www.clark.net/pub/ecn/home.html




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (9 preceding siblings ...)
  1996-08-14  0:00 ` Jon S Anthony
@ 1996-08-14  0:00 ` Ken Garlington
  1996-08-21  0:00 ` Jon S Anthony
  11 siblings, 0 replies; 46+ messages in thread
From: Ken Garlington @ 1996-08-14  0:00 UTC (permalink / raw)



Jon S Anthony wrote:
> 
> In article <dahgq78i0z.fsf@explorer2.clark.net> ecn@explorer2.clark.net (Eric C. Newton) writes:
> 
> > It's a pretty hard sell to say (pardon the syntax, 8-):
> >
> >       struct Person;
> >       Eat(Person);
> >       Walk(Person);
> >       Talk(Person);
> >
> > "That's a person.  It has the features 'Eat, Walk, Talk'."
> >
> > Vs.
> >       class Person
> >       {
> >               Eat();
> >               Walk();
> >               Talk();
> >       };
> >
> 
> I see no reason why _passive_ entities (the so called objects for
> either of the above) should look like they are acting or being
> commanded to act.  If you want that then use an activity which in Ada
> would be modeled by a task:

Here's a more convoluted way to get the syntax in the "right" order.
Granted, it exposes state variables that should be hidden, but by God
the syntax is right!

package Person is

  type State is private;
  Initial_State : constant State;

  type Activity is access procedure ( Using : in out State );
  procedure Eating ( Using : in out State );
  procedure Walking ( Using : in out State );
  procedure Talking ( Using : in out State );

  type Object is tagged
    record
      Eat : Activity := Eating'Access;
      Walk : Activity := Walking'Access;
      Talk : Activity := Talking'Access;
      Current_State : State := Initial_State;
    end record;

private

  type State is
    record
      Stomach_Level : Natural;
      X_Coordinate  : Natural;
      Y_Coordinate  : Natural;
      Volume        : Natural;
    end record;

  Initial_State : constant State := (0,0,0,0);

end Person;

with Person;
procedure Person_Test is

  Joe : Person.Object;

begin

  Joe.Eat(Using => Joe.Current_State);
  Joe.Walk(Using => Joe.Current_State);
  Joe.Talk(Using => Joe.Current_State);

end Person_Test;

:)

-- 
LMTAS - "Our Brand Means Quality"




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (8 preceding siblings ...)
  1996-08-14  0:00 ` Eric C. Newton
@ 1996-08-14  0:00 ` Jon S Anthony
  1996-08-14  0:00 ` Ken Garlington
  1996-08-21  0:00 ` Jon S Anthony
  11 siblings, 0 replies; 46+ messages in thread
From: Jon S Anthony @ 1996-08-14  0:00 UTC (permalink / raw)



In article <dahgq78i0z.fsf@explorer2.clark.net> ecn@explorer2.clark.net (Eric C. Newton) writes:

> When I originally read about Ada 95's support for polymorphism, I
> thought that it *must* support multiple dispatch arguments.  That is,
> if you can make any argument the "dispatcher", why not make more than
> one argument the dispatcher (as in CLOS, or Cecil)?

Basically, because no one knew what the "right" dispatch policy should
be in such cases and no one had any intention of putting in something
like the MOP.  So, it didn't happen.

> would choose the correct method based on the run-time types of both
> obj1 *and* obj2.

But if there are several to choose from at runtime???


> essential in large systems.  But objects are kinda handy abstractions
> as well.  Relying on packages as the ONLY structuring mechanism makes
> objects-as-abstractions a little more obscure because they don't
> provide any structure by themselves.  
> 
> It's a pretty hard sell to say (pardon the syntax, 8-):
> 
> 	struct Person;
> 	Eat(Person);
> 	Walk(Person);
> 	Talk(Person);
> 
> "That's a person.  It has the features 'Eat, Walk, Talk'."
> 
> Vs.
> 	class Person
> 	{
> 		Eat();
> 	 	Walk();
> 		Talk();
> 	};
> 

I see no reason why _passive_ entities (the so called objects for
either of the above) should look like they are acting or being
commanded to act.  If you want that then use an activity which in Ada
would be modeled by a task:

    task type Person is
	entry Wake_Up;
	entry Mow_The_Lawn;
	...
    end Person;

    Joe : Person;

    Joe.Wake_Up; -- Joe now independently goes about eating, walking, talking
    ...
    Joe.Mow_The_Lawn; -- Quit stalling and cut the grass...


>    package Matrixes is

Shrug.  And?


> I keep trying to see packages like I see objects and it just doesn't
> get any easier.

That's because they aren't objects/classes.  They are orthogonal constructs.
Classes are classes (T'Class, e.g.), objects are objects ( Obj : T, e.g.)

> Namespaces are good.  Objects are good.  Yes, Ada 95
> has both, but it is pretty good at hiding the objects.

Huh?  An object is quite explicit and obvious:

    X : T;  -- X is an object for any type T.  Pretty clear and obvious.

> could really use the kind of tools available in Ada.  I just don't
> find myself wishing I could make a procedure dispatch on a type by
> adding a keyword.

The use of "tagged" is indeed controversial...


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (7 preceding siblings ...)
  1996-08-13  0:00 ` Eric C. Newton
@ 1996-08-14  0:00 ` Eric C. Newton
  1996-08-14  0:00 ` Jon S Anthony
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 46+ messages in thread
From: Eric C. Newton @ 1996-08-14  0:00 UTC (permalink / raw)



In article <JSA.96Aug13221742@alexandria> jsa@alexandria (Jon S Anthony) writes:

<We were discussing multiple-dispatch.>

   Basically, because no one knew what the "right" dispatch policy should
   be in such cases and no one had any intention of putting in something
   like the MOP.  So, it didn't happen.

Yes, multiple argument dispatching is a difficult thing to reason
about, and I'm just a lowly mortal.  Ada's syntax only suggested such
a thing to me.  I figured someone else worried about making it work
safely.

   I see no reason why _passive_ entities (the so called objects for
   either of the above) should look like they are acting or being
   commanded to act.  If you want that then use an activity which in Ada
   would be modeled by a task:

Yes, a task is a good model for an active thing.  Perhaps I should
have said "This is a Person.  It manages person-state, and satisfies
person-services, as listed in the encapsulated person class."  But,
you would say: "This is a person.  It represents the private state
used by the services encapsulated in the person package."  

My problem is that I like having *BOTH* a person package *AND* a
person class encapsulation mechanism.  I can live with just one or the
other, but I like both.

   >    package Matrixes is

   Shrug.  And?

The point of the (deleted) example was to show that a package is just
a namespace, and that multiple classes can live in that namespace, and
that the features of the class do not need to be visibly associated
with the dispatch object.  Matrixes encapsulates Matrix *and* Vector
types.  I can list the Matrix and Vector operations willy-nilly within
this namespace.  In C++/Modula-3 I must list the operations on the
private state of Matrix within the Matrix class.  I must list the
operations on the private state of Vector within the Vector class.
There is visible association of dispatch methods and type.

*I* know I can create little packages for each class.  *I* know that
they are equivalent.  I think there is a case to be made that the Ada
approach can be beneficial in some cases (such as in tightly coupled
classes such as Matrix and Vector).  BUT, I think I would miss the
textual grouping and extra encapsulation level.

I'm just trying to cross the bridge between traditional object
languages and the approach taken by Ada.  They share almost no
vocabulary and use different words for similar things, and they look
completely different.

Of course, smalltalk lets you put a method anywhere, at any time,
right?  You rely on the browser to provide the "grouping of methods."
So there's a tradition of other mechanisms, too.

   > I keep trying to see packages like I see objects and it just doesn't
   > get any easier.

   That's because they aren't objects/classes.  They are orthogonal constructs.
   Classes are classes (T'Class, e.g.), objects are objects ( Obj : T, e.g.)

Yes, they are orthogonal, but you *almost* always want a class
encapsulated.  So in other OO languages, I get some encapsulation with
a class, in Ada I have to create a new package.  On the other hand,
there is no need for the C++ "friend".

   > Namespaces are good.  Objects are good.  Yes, Ada 95
   > has both, but it is pretty good at hiding the objects.

   Huh?  An object is quite explicit and obvious:

       X : T;  -- X is an object for any type T.  Pretty clear and obvious.

I was just pointing out that Objects need not be encapsulated with
respect to each other and that dispatching is not obvious at the call
site.

   The use of "tagged" is indeed controversial...

It encourages me to think of Ada's mechanisms as a way add in
dispatching, rather than a means for organizing my runtime
architecture.  Dispatching/polymorphism is a powerful tool for
abstraction.  I suppose that Object-Oriented programmers like myself
are simply looking for the comfortable encapsulated, abstract,
polymorphic entity they know and love in a single construct.  This
discussion has helped me understand the Ada approach, and maybe it
will help me explain it to others.

-Eric

-- 
Eric C. Newton        Software Reuser.
Newton Consulting     Look at all the code I didn't write today!
ecn@clark.net	      http://www.clark.net/pub/ecn/home.html




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

* Re: Ada95 OOP Questions
@ 1996-08-20  0:00 Farshad Nayeri
  0 siblings, 0 replies; 46+ messages in thread
From: Farshad Nayeri @ 1996-08-20  0:00 UTC (permalink / raw)
  Cc: farshad, kalsow, steve


Eric Newton said:

> The point of the (deleted) example was to show that 
> a package is just a namespace, and that multiple classes 
> can live in that namespace, and that the features of 
> the class do not need to be visibly associated
> with the dispatch object.  Matrixes encapsulates 
> Matrix *and* Vector types. I can list the Matrix and 
> Vector operations willy-nilly within this namespace.  

> In C++/Modula-3 I must list the operations on
> the private state of Matrix within the Matrix class. 
> I must list the operations on the private state of 
> Vector within the Vector class.
> There is visible association of dispatch methods and type.

I believe this is an inaccurate representation of the way Modula-3 
organizes namespaces and visibility. Much care went into designing 
namespaces and avoiding problems in the C++ "private" state model. 

Modula-3 has separate mechanisms for encapsulation (modules & 
interfaces) and inheritance and dispatching (object types). 
Using partial revelation--where one interface can reveal partial 
information about various types; others can import only the necessary 
features by importing that interface--Eric can do the kinds of 
groupings he was talking about.

Steve Freeman has written a nice article for Dr. Dobb's Journal,
comparing the encapsulation and grouping facilities of Ada95, 
C++, Eiffel, and Modula-3. He addresses precisely the kinds of issues that
Eric mentioned and goes through code examples to illustrate his
point. A copy of the article is available via the web:

http://www.research.digital.com/SRC/modula-3/html/partial-rev/index.html

Regards, -- Farshad

--
Farshad Nayeri
Critical Mass, Inc.
http://www.cmass.com/

Disclaimer: I am biased!




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

* Re: Ada95 OOP Questions
@ 1996-08-20  0:00 Farshad Nayeri
  1996-08-21  0:00 ` Jon S Anthony
  0 siblings, 1 reply; 46+ messages in thread
From: Farshad Nayeri @ 1996-08-20  0:00 UTC (permalink / raw)
  Cc: farshad, kalsow, steve


Eric Newton said:

> The point of the (deleted) example was to show that 
> a package is just a namespace, and that multiple classes 
> can live in that namespace, and that the features of 
> the class do not need to be visibly associated
> with the dispatch object.  Matrixes encapsulates 
> Matrix *and* Vector types. I can list the Matrix and 
> Vector operations willy-nilly within this namespace.  

> In C++/Modula-3 I must list the operations on
> the private state of Matrix within the Matrix class. 
> I must list the operations on the private state of 
> Vector within the Vector class.
> There is visible association of dispatch methods and type.

While this may be true of C++'s, it is an inaccurate
statement about Modula-3's organization of namespaces and 
visibility of class features. In fact, much care went 
into designing namespaces and avoiding problems in the 
C++ "public/private/protected/friend" model as you describe. 

Modula-3 has separate mechanisms for encapsulation (modules & 
interfaces) vs. inheritance and dispatching (object types). 
An implementor can define an interface which reveals partial 
information about one or more object types; clients can import
only the necessary features by importing the interface that
reveals the right kind of information about (one or more) types.
Anyone with the right level of access to a group of classes, 
that is, anyone who imports the right "private" interface 
to a module, can access the private state of those classes
as prescribed by the implementor of the interface.

Steve Freeman has written a nice article for Dr. Dobb's Journal,
comparing the encapsulation and grouping facilities of Ada95, 
C++, Eiffel, and Modula-3. He addresses precisely the kinds of issues that
Eric mentioned and goes through code examples to illustrate his
point. A copy of the article is available via the Modula-3 home page.

	http://www.research.digital.com/SRC/modula-3/html/

Regards, -- Farshad

Disclaimer: I am biased!
--
Farshad Nayeri
Critical Mass, Inc.
http://www.cmass.com/




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

* Re: Ada95 OOP Questions
  1996-07-28  0:00 Ada95 OOP Questions Spasmo
                   ` (10 preceding siblings ...)
  1996-08-14  0:00 ` Ken Garlington
@ 1996-08-21  0:00 ` Jon S Anthony
  11 siblings, 0 replies; 46+ messages in thread
From: Jon S Anthony @ 1996-08-21  0:00 UTC (permalink / raw)



In article <dazq3xu7ul.fsf@explorer2.clark.net> ecn@explorer2.clark.net (Eric C. Newton) writes:

> My problem is that I like having *BOTH* a person package *AND* a
> person class encapsulation mechanism.  I can live with just one or the
> other, but I like both.

What does this give you?  Certainly you can nest a person "class" package
inside of a personS package.


> The point of the (deleted) example was to show that a package is just
> a namespace, and that multiple classes can live in that namespace, and
> that the features of the class do not need to be visibly associated
> with the dispatch object.

Yes.  And I "shrug" to that.  Same sort of situation for Dylan or
CLOS.  Of course, that doesn't make it "good" by definition or
something.  Just that this is a specific design choice balancing
various requirements, reasons, etc.


> *I* know I can create little packages for each class.  *I* know that
> they are equivalent.  I think there is a case to be made that the Ada
> approach can be beneficial in some cases (such as in tightly coupled
> classes such as Matrix and Vector).  BUT, I think I would miss the
                                              ^^^^^
> textual grouping and extra encapsulation level

Maybe.  But I see the operative word here as "think".  What's really at
issue is "this is what I am used to".  Which is a definite point, but
can also close off potentially "better" alternatives.


> I was just pointing out that Objects need not be encapsulated with
> respect to each other and that dispatching is not obvious at the call
> site.

Actually, dispatching is _more_ obvious at the call site than in
something like Eiffel or C++.  That's because dispatching is a local
thing - _indicated_ at the specific invocation.  In C++ or Eiffel you
indicate this dispatching (virtual in C++) or non dispatching (frozen
in Eiffel [this is not quite the same, but prevents dispatch])
behavior back in the class definition.  Also, once it's made it is
pretty much fixed (you have to go back and hack the class to change
it).  In Ada you pick what you want at the particular call site and
indicate it.  In general this is pretty explicit:

   A : T;

   Op(T'Class(A));  -- Dispatch
   Op(A);           -- No dispatch

or

   A : T'Class; -- Typical of a class wide operation signature which
                -- will dispatch internally for specific behavior

   Op(A); -- dispatches...

In any event for any call, you only need to look around _locally_ to
see if the parameter to the Op is classwide - if so the Op dispatches.
In the other two example cases, you have to go back to the class
definition to be sure.


> abstraction.  I suppose that Object-Oriented programmers like myself
> are simply looking for the comfortable encapsulated, abstract,
> polymorphic entity they know and love in a single construct.  This
> discussion has helped me understand the Ada approach, and maybe it
> will help me explain it to others.

Sounds good to me!


/Jon
-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

* Re: Ada95 OOP Questions
  1996-08-20  0:00 Farshad Nayeri
@ 1996-08-21  0:00 ` Jon S Anthony
  0 siblings, 0 replies; 46+ messages in thread
From: Jon S Anthony @ 1996-08-21  0:00 UTC (permalink / raw)



In article <3219EFDE.7161@cmass.com> Farshad Nayeri <farshad@cmass.com> writes:

> Eric Newton said:
[...]
> > In C++/Modula-3 I must list the operations on
> > the private state of Matrix within the Matrix class. 
> > I must list the operations on the private state of 
> > Vector within the Vector class.
> > There is visible association of dispatch methods and type.
[...]
> Modula-3 has separate mechanisms for encapsulation (modules & 
> interfaces) vs. inheritance and dispatching (object types). 
> An implementor can define an interface which reveals partial 
> information about one or more object types; clients can import
> only the necessary features by importing the interface that
> reveals the right kind of information about (one or more) types.
> Anyone with the right level of access to a group of classes, 
> that is, anyone who imports the right "private" interface 
> to a module, can access the private state of those classes
> as prescribed by the implementor of the interface.

This is done in Ada95 by use of child packages and/or use of
constrained generics.  In fact, it is "cake" and one of the primary
uses of these constructs.


> Steve Freeman has written a nice article for Dr. Dobb's Journal,
> comparing the encapsulation and grouping facilities of Ada95, 
> C++, Eiffel, and Modula-3. He addresses precisely the kinds of issues that
> Eric mentioned and goes through code examples to illustrate his
> point. A copy of the article is available via the Modula-3 home page.

Well, I read the article and I note that since Freeman does not
mention how this sort of stuff is quite easily done in Ada, perhaps he
does not understand the Ada model.  He does a very good job with C++.

In fact, at the first M3 (Association) example, he only mentions the
problems that C++ or Eiffel would have in so "subtyping".  Neither
problem is applicable to Ada.

/Jon
-- 
Jon Anthony
Organon Motives, Inc.
1 Williston Road, Suite 4
Belmont, MA 02178

617.484.3383
jsa@organon.com





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

end of thread, other threads:[~1996-08-21  0:00 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-07-28  0:00 Ada95 OOP Questions Spasmo
1996-07-28  0:00 ` David C. Hoos, Sr.
1996-07-28  0:00   ` Spasmo
1996-07-28  0:00 ` Andre Spiegel
1996-07-28  0:00   ` Spasmo
1996-07-29  0:00     ` Thomas Kendelbacher
1996-07-31  0:00       ` Spasmo
1996-08-01  0:00         ` Thomas Kendelbacher
1996-08-02  0:00         ` Gene Ouye
1996-08-01  0:00       ` Jon S Anthony
1996-07-30  0:00     ` David Wheeler
1996-07-31  0:00       ` Spasmo
1996-07-30  0:00     ` Ken Garlington
1996-08-04  0:00       ` Spasmo
1996-07-29  0:00 ` Andre Spiegel
1996-07-29  0:00   ` David Wheeler
1996-07-30  0:00     ` Spasmo
1996-07-30  0:00     ` Spasmo
1996-07-29  0:00   ` Thomas Kendelbacher
1996-08-02  0:00     ` Robert Dewar
1996-08-05  0:00       ` Thomas Kendelbacher
1996-08-06  0:00         ` Robert Dewar
1996-08-06  0:00           ` Thomas Kendelbacher
1996-08-06  0:00             ` Robert A Duff
1996-08-07  0:00               ` Robert Dewar
1996-08-08  0:00                 ` Robert A Duff
1996-08-09  0:00                   ` Robert Dewar
1996-08-12  0:00             ` Robert I. Eachus
1996-08-08  0:00           ` Theodore E. Dennison
1996-08-09  0:00             ` Robert Dewar
1996-08-12  0:00             ` Joel VanLaven
1996-08-06  0:00         ` Robert I. Eachus
1996-08-10  0:00         ` Chris Morgan
1996-07-30  0:00 ` Andre Spiegel
1996-07-30  0:00 ` Andre Spiegel
1996-07-30  0:00 ` Robert I. Eachus
1996-08-01  0:00 ` Jon S Anthony
1996-08-13  0:00 ` Eric C. Newton
1996-08-14  0:00 ` Eric C. Newton
1996-08-14  0:00 ` Jon S Anthony
1996-08-14  0:00 ` Ken Garlington
1996-08-21  0:00 ` Jon S Anthony
  -- strict thread matches above, loose matches on Subject: below --
1996-08-08  0:00 W. Wesley Groleau (Wes)
1996-08-20  0:00 Farshad Nayeri
1996-08-20  0:00 Farshad Nayeri
1996-08-21  0:00 ` Jon S Anthony

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