comp.lang.ada
 help / color / mirror / Atom feed
* Re: Ada OO Mechanism
  1999-05-20  0:00 Ada OO Mechanism Shawn M. Root
@ 1999-05-20  0:00 ` Samuel Mize
  1999-05-20  0:00   ` David Botton
  1999-05-24  0:00   ` Hyman Rosen
  1999-05-21  0:00 ` Dale Stanbrough
  1 sibling, 2 replies; 116+ messages in thread
From: Samuel Mize @ 1999-05-20  0:00 UTC (permalink / raw)


Original post rearranged a little.

Shawn M. Root <smroot@orbitworld.net> wrote:
> ... some people were saying
> that the Ada OO mechanism was counterintuitive.  I tend to agree.
...
>Perhaps I've missed
> the point, but it seems like a Class construct would fit in well with
> the Ada way of doing things.  It seems like a logical evolution from a
> package, to a generic package, to a class.

First off, the class construct is used in other popular languages, so
your argument is not without merit.  It would be familiar, and its
existence would ease the transition from those other languages.

However, Ada already had some of the features that were added to other
languages by object-oriented extensions.  (Not to name any names, but
it's initial is "C".)

For instance, the "class" in C++ is the construct for object-oriented
programming.  It's also the construct for encapsulation of related
functions, user definition and extension of types, and templates.

But, except for OO programming, all of these were ALREADY in Ada.

So the designers of Ada 95 were faced with a dilemma: should they
introduce a familiar-looking set of "OO" features that duplicate
existing features of the language, or should they introduce only the
new features needed to make Ada 83 completely OO-capable, when it was
already almost an OOP language to start with?

For fair or foul, they took the second path.  I personally think it
was the right technical decision, but it creates a PR difficulty
because people think that the C++ way is the "right" OO way.  In fact,
it's ONE approach to OO technology -- neither the best nor the worst,
but certainly the most popular at present.

I feel that the Ada 95 team made the right technical decision because
it kept the language features more orthogonal -- that is, we didn't
wind up with a bunch of different features doing the same thing.
Also, as you stray from the strict C++ model, you find that it's much
easier to define your abstractions clearly in Ada.  For instance, you
don't need a "friends" capability, because encapsulation is not
provided by object classes.

There are two areas where I've seen strongly-held objections to the
Ada model:

1. There isn't a "class" construct that encloses the definition of a
class.

First note that in Ada terms, we aren't talking about a class, but
about a type.  A C++ "class" defines a template for data storage, and
a set of operations on instances of that template.  In Ada, this is a
type.  In Ada terminology, a "class" is a family of types.  That's why
a "class-wide" parameter can accept a value of a given type OR any of
its descendants: that's an Ada "class."  In C++ terms, it can accept a
value of a given class or any subclass of that class.

Anyway, in Ada, if you want to encapsulate the type definition with
its primitive operations, you put a package around it.  It just
doesn't use the word "class," but it achieves exactly the same thing
as a C++ class definition.

The advantage to the Ada approach appears when classes are tightly
coupled.  The standard example is an OO type and an active iterator
over that type.  The iterator needs to see the "innards" of the other
type.  In C++ you have to define the iterator class as a "friend" of
the other class.  In Ada you can simply encapsulate both types in the
same package, or with the iterator as a child package.

There are other OO design approaches that are harder to implement in
C++ than in Ada, because C++ strongly supports one specific view of
object-oriented technology.

I personally think it would be useful to define some pragma or
comment-flag tags that will encode, in the code, what design approach
is being used.  Some things could be checked for you that are not
currently checked, and an ASIS-based tool could look through the
compiled results, find what design approach was intended for a given
chunk of code, and check those specific constraints.

Other people have reacted violently against this idea, for reasons I
did not find clear.  It seemed they were arguing that not all code
should conform to the C++ model, and I certainly agree.  I do think it
would be useful to encode whether or not a given tagged type was
designed to that model, or to another model, and that the compiler
suite could check it against the constraints of whatever model it was
designed against.

But anyway, my overall point is that encapsulation of a type with its
primitive operations (in C++ terms, a class) is done with the
encapsulation operator in Ada, which is the package.  A C++-style
"class" would be a redundant encapsulation operator.

2. You can't use "object.method" notation.

This is another case where the Ada design gives less support to one
specific view of OO technology, because it's supporting more views of
OO technology.

Specifically, the C++ model is that one object "receives a message"
and operates on it, and this is modeled with a function call.

The Ada model is, loosely, that a function call identifies an action
to occur (or a message, if you prefer), a set of related information
(the non-controlling parameters), and a set of objects.  These
objects, all of the same class, cooperate somehow to accomplish the
action (or respond to the message).

So, if you want to design using a specific "recipient" for each
"message," you can do so.  One common approach for this is to use the
first parameter for the "recipient."

You don't get to call out the recipient as part of the syntax, but on
the other hand you don't have to arbitrarily pick one "recipient" if
you aren't using that model of object interaction.

> This
> concern was dismissed by others as being merely "syntactic sugar", and
> claims were made that the Ada mechanism is actually easier to use than
> the C++ style.  These arguments seemed misplaced to me.  I thought that
> one of the goals of Ada was to focus on the reader of the code, not the
> writer.  Therefore if this "syntactic sugar" makes code easier to
> understand, then it would be a good thing, right?  

I hope I've clarified the point that, in some cases, the syntax you
are talking about would become LESS clear, not clearer.

The argument is really whether the language should specifically
support one model of OO technology, to the detriment of other models,
simply because the currently-most-popular OO language uses that model.

> The syntax would even be
> similar since (at least where I work) use clauses are rarely used.
> We write
> Package_Name.Procedure;
> so what's wrong with
> Class_Name.Method;

Nothing.  In fact, you can do that now with a one-class-per-package
approach, and I don't think you can do it in C++.

I note that people who want "object.method" notation often refer to it
as "class.method" notation.  This suggests to me that their objection
is not based in the structure or meaning of the facility, but is about
the code having an unfamiliar "look," because they so often mis-state
the structure and meaning of what they're requesting.

This isn't meant as a dig at you.  Rather, I'm pointing out that this
issue really seems to be that Ada has a different "look and feel" than
C++ or Smalltalk.  Adding a "class" encapsulator and "object.method"
notation certainly won't change that!

Trying to write Ada code that conforms to a C++ view of syntax and
semantics is as foolish as trying to write C++ code to look like Ada.

To some extent, if you could just uproot notations from one language
and plop them down in the other, there'd be no reason to have both
languages.  I feel that both C++ and Ada have real value.  I feel it's
good to have BOTH languages -- our understanding of the deeper issues
is greatly enhanced by having more than one way to express them.

Philosophy final exam: "Describe human thought.  Compare and contrast
with any other kind of thought."

> Maybe I just don't understand the issues.  I would appreciate any help
> in making this clear.

I hope you found this helpful.

> Shawn M. Root

Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-20  0:00   ` David Botton
@ 1999-05-20  0:00     ` Samuel Mize
  1999-05-20  0:00       ` David Botton
  0 siblings, 1 reply; 116+ messages in thread
From: Samuel Mize @ 1999-05-20  0:00 UTC (permalink / raw)


David Botton <David@Botton.com> wrote:
>> 
>> Trying to write Ada code that conforms to a C++ view of syntax and
>> semantics is as foolish as trying to write C++ code to look like Ada.
> 
> I don't think it is so foolish to write C++ code that looks like Ada
> code.

Well, I meant in both cases "writing code that conforms to the language
X view of syntax and semantics."  For perfect clarity, I should have
repeated the entire phrase in the second parallel clause.  I hope you'll
agree that it would not be good C/C++ coding style to, for instance, use
preprocessor macros to turn "BEGIN" and "END" into "{" and "}" so your
C/C++ code would look more like Ada.  Each language has a "view of
syntax and semantics" that defines it, and you should work within its
own view of itself, not try to force the view of other languages on it.

> IMHO Good C++ code should look very much like Ada. Clear separation
> between specs and body. Clear long object names and variables,
> documentation, etc.

You're saying that good C++ should look very much like GOOD Ada, in
those ways that are language-independent.  But it will still use C++
syntax and semantics.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-21  0:00 ` Dale Stanbrough
@ 1999-05-20  0:00   ` bob
  1999-05-21  0:00     ` Dale Stanbrough
  1999-05-21  0:00   ` Richard D Riehle
  1999-05-25  0:00   ` Don Overheu
  2 siblings, 1 reply; 116+ messages in thread
From: bob @ 1999-05-20  0:00 UTC (permalink / raw)


In article <dale-2105990836310001@r1021c-18.ppp.cs.rmit.edu.au>,
dale@cs.rmit.edu.au says...

> 
>I actually like the method.operation notation, but I don't find the lack
>of it in Ada a really big problem. It _is_ syntactic sugar, in as much as
>there are no semantic differences that can be attributed to it.
>

Then why do most women say that they prefer it when a man talk 
love things to them in French than in any other language? 

It is true. Ask any woman.

Why do "I love you" in French is more appealing to a woman ears than
"I love you" in English or German or Russian etc? and they respond
better to it that way?

Same semantics, (expressing love), but different synatx (sound wise). So, 
what you think is only syntactic sugar, for others might be more. It might 
have some deeper feelings associated with it, that brings up some images
associated with personal emotions. 

Bob
who_needs_to_learn_french_to_improve_his_social_life





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

* Ada OO Mechanism
@ 1999-05-20  0:00 Shawn M. Root
  1999-05-20  0:00 ` Samuel Mize
  1999-05-21  0:00 ` Dale Stanbrough
  0 siblings, 2 replies; 116+ messages in thread
From: Shawn M. Root @ 1999-05-20  0:00 UTC (permalink / raw)


Greetings,

    I've been lurking on this newsgroup for about a year now and would
first like to thank all of you who contribute to this group regularly
for your very interesting and informative discussions.  These
discussions have led me to a better, though still very limited,
understanding of Ada.

    I would like to ask a question, however.  In a recent thread
entitled "A question for my personal knowledge" some people were saying
that the Ada OO mechanism was counterintuitive.  I tend to agree.  This
concern was dismissed by others as being merely "syntactic sugar", and
claims were made that the Ada mechanism is actually easier to use than
the C++ style.  These arguments seemed misplaced to me.  I thought that
one of the goals of Ada was to focus on the reader of the code, not the
writer.  Therefore if this "syntactic sugar" makes code easier to
understand, then it would be a good thing, right?  Perhaps I've missed
the point, but it seems like a Class construct would fit in well with
the Ada way of doing things.  It seems like a logical evolution from a
package, to a generic package, to a class.  The syntax would even be
similar since (at least where I work) use clauses are rarely used.
We write
Package_Name.Procedure;
so what's wrong with
Class_Name.Method;

Maybe I just don't understand the issues.  I would appreciate any help
in making this clear.

Thanks.
--
Shawn M. Root







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

* Re: Ada OO Mechanism
  1999-05-20  0:00 ` Samuel Mize
@ 1999-05-20  0:00   ` David Botton
  1999-05-20  0:00     ` Samuel Mize
  1999-05-24  0:00   ` Hyman Rosen
  1 sibling, 1 reply; 116+ messages in thread
From: David Botton @ 1999-05-20  0:00 UTC (permalink / raw)


> 
> Trying to write Ada code that conforms to a C++ view of syntax and
> semantics is as foolish as trying to write C++ code to look like Ada.

I don't think it is so foolish to write C++ code that looks like Ada
code.

IMHO Good C++ code should look very much like Ada. Clear separation
between specs and body. Clear long object names and variables,
documentation, etc.

In fact even C++ standards have been working hard to add more Ada in to
C++, for example packages (name spaces)

David Botton

Writing ADA for Ada is like C PLUS PLUS for C++.




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

* Re: Ada OO Mechanism
  1999-05-20  0:00     ` Samuel Mize
@ 1999-05-20  0:00       ` David Botton
  0 siblings, 0 replies; 116+ messages in thread
From: David Botton @ 1999-05-20  0:00 UTC (permalink / raw)



> I hope you'll
> agree that it would not be good C/C++ coding style to, for instance, use
> preprocessor macros to turn "BEGIN" and "END" into "{" and "}" so your
> C/C++ code would look more like Ada.

Actually I should give it a try. I should add a // after the "{" and "}"
so I can do ( and of course define procedure as void, print_line as
printf, and new_line as printf("\n") ):

procedure main()
begin -- main
	put("Hello World");
	new_line;
end main;

Much better now :-)

David Botton




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

* Re: Ada OO Mechanism
  1999-05-21  0:00 ` Dale Stanbrough
  1999-05-20  0:00   ` bob
@ 1999-05-21  0:00   ` Richard D Riehle
  1999-05-21  0:00     ` Marin David Condic
  1999-05-21  0:00     ` Shawn M. Root
  1999-05-25  0:00   ` Don Overheu
  2 siblings, 2 replies; 116+ messages in thread
From: Richard D Riehle @ 1999-05-21  0:00 UTC (permalink / raw)


In article <dale-2105990836310001@r1021c-18.ppp.cs.rmit.edu.au>,
	dale@cs.rmit.edu.au (Dale Stanbrough) wrote:

>" I would like to ask a question, however.  In a recent thread
>  entitled "A question for my personal knowledge" some people were saying
>  that the Ada OO mechanism was counterintuitive.  I tend to agree.  This
>  concern was dismissed by others as being merely "syntactic sugar", and
>  claims were made that the Ada mechanism is actually easier to use than
>  the C++ style."
>
>I actually like the method.operation notation, but I don't find the lack
>of it in Ada a really big problem. It _is_ syntactic sugar, in as much as
>there are no semantic differences that can be attributed to it.

I know some languages in which the verb is the last word of a sentence.
Some other languages are subject-verb-object, others have entirely 
different syntax.  So when I hear someone say that Ada is 
counterintuitive or C++ is counterintuitive or Object COBOL is 
counterintuitive, I understand that they mean, "This is not the way
I am used to thinking about things."   That does not mean it is 
counterintuitive.  It simply means they have had difficulty learning
a new programming language just as they might have trouble learning a
new spoken language.  When I hear someone speak of "natural" language,
I have to wonder what they are talking about.  

There is absolutely nothing wrong with the syntax of C++.  Nothing
wrong or counterintuitive about the syntax of Ada or Eiffel. And 
there is nothing counterintuitive about the object model of the 
emerging COBOL standard.  If you want to say, "I am having trouble
learning this language because it is not what I am used to," fine.
That is accepting responsibility for your own difficulty.  Lots of
great ideas throughout history have been counterintuitive. The
Greeks could not conceive of a symbol for zero. Aristotle thought
it was intutitive to begin counting from two because there was no
point in counting if there only a single instance.  Before the 
invention of calculus, the notion of a limit was counterintuitive.

The statement, "I find such and such to be counterintuitive," is a
tired old excuse for failing to work hard enough to understand some
idea.  It does not apply to languages;  especially not to programming
languages.

Richard Riehle
richard@adaworks.com
http://www.adaworks.com  
 




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

* Re: Ada OO Mechanism
  1999-05-20  0:00 Ada OO Mechanism Shawn M. Root
  1999-05-20  0:00 ` Samuel Mize
@ 1999-05-21  0:00 ` Dale Stanbrough
  1999-05-20  0:00   ` bob
                     ` (2 more replies)
  1 sibling, 3 replies; 116+ messages in thread
From: Dale Stanbrough @ 1999-05-21  0:00 UTC (permalink / raw)


" I would like to ask a question, however.  In a recent thread
  entitled "A question for my personal knowledge" some people were saying
  that the Ada OO mechanism was counterintuitive.  I tend to agree.  This
  concern was dismissed by others as being merely "syntactic sugar", and
  claims were made that the Ada mechanism is actually easier to use than
  the C++ style."


I actually like the method.operation notation, but I don't find the lack
of it in Ada a really big problem. It _is_ syntactic sugar, in as much as
there are no semantic differences that can be attributed to it.

I think you get used to using whatever you use. Perhaps I would find
method.operation marginally better (you can easily find the dispatching
operand!), and it seems a bit more contextual (which i think is how 
people work).

Dale




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

* Re: Ada OO Mechanism
  1999-05-21  0:00   ` Richard D Riehle
  1999-05-21  0:00     ` Marin David Condic
@ 1999-05-21  0:00     ` Shawn M. Root
  1999-05-21  0:00       ` Richard D Riehle
  1 sibling, 1 reply; 116+ messages in thread
From: Shawn M. Root @ 1999-05-21  0:00 UTC (permalink / raw)



Richard D Riehle wrote in message
<7i28qu$1bc@dfw-ixnews11.ix.netcom.com>...
:In article <dale-2105990836310001@r1021c-18.ppp.cs.rmit.edu.au>,
: dale@cs.rmit.edu.au (Dale Stanbrough) wrote:
:
:>" I would like to ask a question, however.  In a recent thread
:>  entitled "A question for my personal knowledge" some people were
saying
:>  that the Ada OO mechanism was counterintuitive.  I tend to agree.
This
:>  concern was dismissed by others as being merely "syntactic sugar",
and
:>  claims were made that the Ada mechanism is actually easier to use
than
:>  the C++ style."
:>
:>I actually like the method.operation notation, but I don't find the
lack
:>of it in Ada a really big problem. It _is_ syntactic sugar, in as
much as
:>there are no semantic differences that can be attributed to it.
:
:I know some languages in which the verb is the last word of a
sentence.
:Some other languages are subject-verb-object, others have entirely
:different syntax.  So when I hear someone say that Ada is
:counterintuitive or C++ is counterintuitive or Object COBOL is
:counterintuitive, I understand that they mean, "This is not the way
:I am used to thinking about things."   That does not mean it is
:counterintuitive.  It simply means they have had difficulty learning
:a new programming language just as they might have trouble learning a
:new spoken language.  When I hear someone speak of "natural" language,
:I have to wonder what they are talking about.
:
Actually it does mean that it is counterintuitive.  Counterintuitive
means that what you found is not what you expected to find.  This is a
relative term, not an absolute.  What is counterintuitive for me, may
be readily obvious to you.  Intuition has nothing to do with "thinking
about things". It has to do with the understanding or knowing of
something _without_ overt reasoning.  Furthermore, it does not mean
that someone had difficulty learning a new programming language.  It
simply means that, in my particular case, the Ada OO mechanisms seem
less obvious than the C++ mechanisms.

:There is absolutely nothing wrong with the syntax of C++.  Nothing
:wrong or counterintuitive about the syntax of Ada or Eiffel. And
:there is nothing counterintuitive about the object model of the
:emerging COBOL standard.  If you want to say, "I am having trouble
:learning this language because it is not what I am used to," fine.
:That is accepting responsibility for your own difficulty.  Lots of
:great ideas throughout history have been counterintuitive. The
:Greeks could not conceive of a symbol for zero. Aristotle thought
:it was intutitive to begin counting from two because there was no
:point in counting if there only a single instance.  Before the
:invention of calculus, the notion of a limit was counterintuitive.
:

Yes, but after calculus was invented, and the concept of the limit was
understood, would you invent a new way to do limits if the new way
offered no significant advantages over the old way?

:The statement, "I find such and such to be counterintuitive," is a
:tired old excuse for failing to work hard enough to understand some
:idea.  It does not apply to languages;  especially not to programming
:languages.
:

Again, I don't know where you got this impression.  Perhaps others
you've spoken to have used the "counterintuitive excuse" to cover
difficulties in learning.  However, that is not the case here.  I was
introduced to Ada before C++ so, if anything, I had more trouble
learning the C++ way of doing things.  My comments have nothing to do
with not working hard enough to understand certain ideas.  I understand
the ideas and concepts involved.  I understand the other side's
arguments.  So far, however, I don't agree with them.

--
Shawn M. Root







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

* Re: Ada OO Mechanism
  1999-05-21  0:00   ` Richard D Riehle
@ 1999-05-21  0:00     ` Marin David Condic
  1999-05-21  0:00       ` Dan Nagle
  1999-05-21  0:00       ` Steve
  1999-05-21  0:00     ` Shawn M. Root
  1 sibling, 2 replies; 116+ messages in thread
From: Marin David Condic @ 1999-05-21  0:00 UTC (permalink / raw)


Richard D Riehle wrote:
> 
> The statement, "I find such and such to be counterintuitive," is a
> tired old excuse for failing to work hard enough to understand some
> idea.  It does not apply to languages;  especially not to programming
> languages.
> 
Dittos!

I think this probably also applies to the "first language" theory of
programming and explains why lots of programmers accustomed to Fortran
had such hostility towards Ada. My first language was Pascal and I found
Ada to be quite comfortable, albeit substantially larger. I did quite a
bit of Fortran programming, but always keeping in mind Pascal's flow
structures, etc., which resulted in much more reliable and easier to
understand Fortran code. Yet people I knew who had dealt strictly with
Fortran found it difficult to deal with things like defining variables
before they used them, lack of common blocks, etc. Programming in a new
language definitely requires that you give up your preconceived notions
of how something "ought" to look.

MDC
-- 
Marin David Condic
Real Time & Embedded Systems, Propulsion Systems Analysis
United Technologies, Pratt & Whitney, Large Military Engines
M/S 731-95, P.O.B. 109600, West Palm Beach, FL, 33410-9600
***To reply, remove "bogon" from the domain name.***

Visit my web page at: http://www.flipag.net/mcondic




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

* Re: Ada OO Mechanism
  1999-05-21  0:00     ` Marin David Condic
  1999-05-21  0:00       ` Dan Nagle
@ 1999-05-21  0:00       ` Steve
  1 sibling, 0 replies; 116+ messages in thread
From: Steve @ 1999-05-21  0:00 UTC (permalink / raw)


In article <37457752.7A73DF4D@pwfl.com>, Marin says...

 
>I did quite a
>bit of Fortran programming, but always keeping in mind Pascal's flow
>structures, etc., which resulted in much more reliable and easier to
>understand Fortran code. Yet people I knew who had dealt strictly with
>Fortran found it difficult to deal with things like defining variables
>before they used them, lack of common blocks, etc. 

The reason they had trouble with it, is simple. FORTRAN programmers, by
definition, are mostly scientists and engineers from different disciplines
other than computer science, i.e. their main profession is not software,
but they use software as a tool to do help them with their main profession,
which is engineering (such as Civil eng., electrical, etc..)

So, as long as it what they wrote works, they do not understand
why you need to spend more time to 'improve' it.

I've had to maintain and fix code written by PhD's in other fields and 
engineers like the above, and they write the worst code any one can see. 
I think there should be a rule against those people writing code, at least
code that need to be maintained by someone else. 

Imagine if you had hard time dealing with FORTRAN written by those people,
I had to look at Pearl code written by them! I had nightmares for days after
that experience.


Steve 





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

* Re: Ada OO Mechanism
  1999-05-20  0:00   ` bob
@ 1999-05-21  0:00     ` Dale Stanbrough
  0 siblings, 0 replies; 116+ messages in thread
From: Dale Stanbrough @ 1999-05-21  0:00 UTC (permalink / raw)


bob wrote:

" Same semantics, (expressing love), but different synatx (sound wise). So, 
  what you think is only syntactic sugar, for others might be more. It might 
  have some deeper feelings associated with it, that brings up some images
  associated with personal emotions."


I'll keep that in mind next time I compile an Ada program with a woman
as the target.

Dale




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

* Re: Ada OO Mechanism
  1999-05-21  0:00     ` Shawn M. Root
@ 1999-05-21  0:00       ` Richard D Riehle
  1999-05-25  0:00         ` Shawn M. Root
  0 siblings, 1 reply; 116+ messages in thread
From: Richard D Riehle @ 1999-05-21  0:00 UTC (permalink / raw)


In article <7i2pqn$qak$1@news.orbitworld.net>,
	"Shawn M. Root" <smroot@orbitworld.net> wrote:

>:So when I hear someone say that Ada is
>:counterintuitive or C++ is counterintuitive or Object COBOL is
>:counterintuitive, I understand that they mean, "This is not the way
>:I am used to thinking about things."   That does not mean it is
>:counterintuitive.  It simply means they have had difficulty learning
>:a new programming language just as they might have trouble learning a
>:new spoken language.  When I hear someone speak of "natural" language,
>:I have to wonder what they are talking about.
>:
>Actually it does mean that it is counterintuitive.  Counterintuitive
>means that what you found is not what you expected to find.  This is a
>relative term, not an absolute.  What is counterintuitive for me, may
>be readily obvious to you.  Intuition has nothing to do with "thinking
>about things". 

 I wonder if I want someone writing software for a pacemaker who is
 not "thinking about things."  Intuition strikes me as a psychological
 concept that implies that one is "thinking about things" differently
 than through the use of more ordinary reasoning.  I am willing to 
 accept the notion of intuition as an important element of problem
 solving.  However, the more I consider the term "counterintuitive" 
 the more counterintuitive it seems the word might be.  Perhaps it is 
 a self-cancelling concept, sort of like (A or not A).  

>It has to do with the understanding or knowing of
>something _without_ overt reasoning.  Furthermore, it does not mean
>that someone had difficulty learning a new programming language.  It
>simply means that, in my particular case, the Ada OO mechanisms seem
>less obvious than the C++ mechanisms.

 The fact that some idea is not obvious makes it counterintuitive?  That 
 notion, in itself, should make one suspicious of any effort to reach
 a conclusion by declaring that this or that is counterintuitive.  Once
 again reaching far back in the history of mathematics, when algorismics
 was introduced to Europe, there was a great uproar.  People found their
 abacus-based counting much more comfortable, much more intutitive. The
 fact that it originated in a non-Christian community made it even more
 unacceptable to many.  Today, the principles of accounting are a vestige
 of the early abacus-based model, and accounting is regarded by many
 algebraicists as being counterintuitive.  

 I do not believe one should become too comfortable with the notion of
 counterintuitive as an excuse for failure to learn some new idea.  In
 such cases, the failure may be that of the learner, not of the idea.

>
>Yes, but after calculus was invented, and the concept of the limit was
>understood, would you invent a new way to do limits if the new way
>offered no significant advantages over the old way?

 The notion of limit did occur to earlier mathematics. It was simply
 not adopted, perhaps because it was counterintuitive.  If you have
 watched young freshman struggle with calculus, even today, the idea
 of limit still remains counterintuitive for many of them.

>
>Again, I don't know where you got this impression.  Perhaps others
>you've spoken to have used the "counterintuitive excuse" to cover
>difficulties in learning.  However, that is not the case here.  I was
>introduced to Ada before C++ so, if anything, I had more trouble
>learning the C++ way of doing things.  My comments have nothing to do
>with not working hard enough to understand certain ideas.  I understand
>the ideas and concepts involved.  I understand the other side's
>arguments.  So far, however, I don't agree with them.

 Perhaps it depends on where one stands to examine the issues.  Certainly,
 it is depends on what _arbitrary_ foundations one selects to support
 the argument.  When I look at a pencil immersed in water, it is clear
 to me that the pencil becomes bent.  Unless I understand some additional
 physics, I will not realize that the pencil is not actually bent,
 even though it seems so obvious from my simple viewpoint that it is.
 
 It seems to me that, when evaluating software tools and languages, we
 need a more comprehensive view of the problem, one that does not reject
 some perfectly good approach by suggesting that some starting point for
 a solution seems counterintuitive.  It is often the intuition on which
 the counterintuitive conclusion is based that makes the counterintuitive
 viewpoint the best place to begin looking for a solution.  If Ada is
 counterintuitive, perhaps that is a good thing, especially when seeking
 solutions to problems of designing large-scale, safety-critical software. 

 Richard Riehle
 richard@adaworks.com
 http://www.adaworks.com 




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

* Re: Ada OO Mechanism
  1999-05-21  0:00     ` Marin David Condic
@ 1999-05-21  0:00       ` Dan Nagle
  1999-05-24  0:00         ` Marin David Condic
  1999-05-21  0:00       ` Steve
  1 sibling, 1 reply; 116+ messages in thread
From: Dan Nagle @ 1999-05-21  0:00 UTC (permalink / raw)


Hello,

Marin David Condic wrote:
> 
<snip requoted >

> I think this probably also applies to the "first language" theory of
> programming and explains why lots of programmers accustomed to Fortran
> had such hostility towards Ada. 

Well, my first language (after assembler) was Fortran, and I'm finding
Ada to be one of the most attractive languages around.

I think both Fortran and Ada are high level languages designed for
a particular pupose(s) and which are both very pratical languages
for programming.  Both exhibit a high degree of awareness of and
sympathy to optimization issues, and generally with issues of
what's going on under-the-hood.

> My first language was Pascal and I found
> Ada to be quite comfortable, albeit substantially larger. I did quite a
> bit of Fortran programming, but always keeping in mind Pascal's flow
> structures, etc., which resulted in much more reliable and easier to
> understand Fortran code. Yet people I knew who had dealt strictly with
> Fortran found it difficult to deal with things like defining variables
> before they used them, lack of common blocks, etc.

Again, my experiences are different.  I've always found Fortran
programmers treated COMMONs as just another kind of data declared
in the main program.

I believe the Fortran standards committee is looking at Ada as they
work out how OO will appear in Fortran.

> Programming in a new
> language definitely requires that you give up your preconceived notions
> of how something "ought" to look.

Agreed.  What's interesting to me is how different folks can program
in the same language and come away with such different viewpoints.
To me, Pascal has always been baby-Fortran with a lot of restrictive
rules (and the unspoken claim that following the rules meant you'd
never make a logic error!).

<snip sig>

-- 

Cheers!
Dan Nagle		dnagle@erols.com
Purple Sage Computing Solutions, Inc.




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

* Re: Ada OO Mechanism
  1999-05-24  0:00       ` Hyman Rosen
  1999-05-24  0:00         ` David Starner
@ 1999-05-24  0:00         ` Mike
  1999-05-25  0:00           ` Robert Dewar
  1 sibling, 1 reply; 116+ messages in thread
From: Mike @ 1999-05-24  0:00 UTC (permalink / raw)


In article <t7g14mqe7b.fsf@calumny.jyacc.com>, Hyman says...
>
>Robert Dewar <robert_dewar@my-dejanews.com> writes:
>> Well obviously the case of extending an algebra that implements
>> symmetrical binary operators is a case more easily handled in
>> Ada than in C, I assume a specific example is not needed here?
>
>Actually, I would like a specific example - 

Prof. Dewar is not adopt to giving examples. He likes to give
theories, but not examples, that is why he is a prof. :)

Mike
 





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

* Re: Ada OO Mechanism
  1999-05-24  0:00         ` David Starner
@ 1999-05-24  0:00           ` bob
  1999-05-24  0:00             ` David Starner
  0 siblings, 1 reply; 116+ messages in thread
From: bob @ 1999-05-24  0:00 UTC (permalink / raw)


In article <3749E9EC.2842436A@aasaa.ofe.org>, David says...
>
 
>Think of vectors and the dot product. C++ forces you to view one vector
>as significant (a becomes "this" inside dot function, it's called
>a.dot(b)), even though in a dot b, a and b are equal significance - dot
>product is a symmetric function. Ada makes them of equal importnatce in
>the dot function body and call.

Are sure you are not talking about Java (which does not have user defined
operators) ?

You have to do the above in Java 'a.dot(b)'

but in C++, (unless '.' is one of those few things that are not
allowed to be redefined), I can write 'a.b' just fine, why not?

Bob
 





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

* Re: Ada OO Mechanism
  1999-05-21  0:00       ` Dan Nagle
@ 1999-05-24  0:00         ` Marin David Condic
  0 siblings, 0 replies; 116+ messages in thread
From: Marin David Condic @ 1999-05-24  0:00 UTC (permalink / raw)


Dan Nagle wrote:
> 
> Well, my first language (after assembler) was Fortran, and I'm finding
> Ada to be one of the most attractive languages around.
> 
No argument here - I think lots of people are capable of switching from
any one language to any other and knowledge of any one language does not
"cripple" someone's ability to use the other. My point was that there
were lots of Fortran programmers who I knew resisted Ada because it
wasn't Fortran with a slightly different syntax. They were used to a
certain style and didn't want to (or know how to) put it aside and look
at Ada without the preconceived notions.

> I think both Fortran and Ada are high level languages designed for
> a particular pupose(s) and which are both very pratical languages
> for programming.  Both exhibit a high degree of awareness of and
> sympathy to optimization issues, and generally with issues of
> what's going on under-the-hood.
> 
I'm glad you mention the "sympathy for optimization" aspects. Ada took a
lot of dings in its early days for being slow. I think it was a case of
compiler writers not yet understanding the language and building partial
implementations which wound up hamstrung when the more complicated
features were to be addressed. That always bothered me because I didn't
see anything in the language rules which would make it inherently
inefficient. Obviously, these days, good quality optimization is being
done and Ada code tends to be on a par with Fortran for speed. (In most
cases - YMMV - implementation dependent - other general disclaimers! :-)

> 
> I believe the Fortran standards committee is looking at Ada as they
> work out how OO will appear in Fortran.
> 
It would be wise for any standards committee to look at how things are
done in other languages. I think Ada has a lot to offer in the way of
insights on how to go about implementing OO in a "general purpose"
language.


> Agreed.  What's interesting to me is how different folks can program
> in the same language and come away with such different viewpoints.
> To me, Pascal has always been baby-Fortran with a lot of restrictive
> rules (and the unspoken claim that following the rules meant you'd
> never make a logic error!).
> 
I had always considered the block-structured, declare-before-use,
"restrictive rules" aspects of Pascal (along with its small size in the
original incarnation) was dramatically different from Fortran. But I
suppose it is closer to Fortran than, say, Lisp. So I guess there are
perspective issues too.

MDC
-- 
Marin David Condic
Real Time & Embedded Systems, Propulsion Systems Analysis
United Technologies, Pratt & Whitney, Large Military Engines
M/S 731-95, P.O.B. 109600, West Palm Beach, FL, 33410-9600
***To reply, remove "bogon" from the domain name.***

Visit my web page at: http://www.flipag.net/mcondic




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

* Re: Ada OO Mechanism
  1999-05-24  0:00   ` Hyman Rosen
@ 1999-05-24  0:00     ` Robert Dewar
  1999-05-24  0:00       ` Hyman Rosen
  1999-05-25  0:00     ` Samuel Mize
  1999-06-03  0:00     ` Matthew Heaney
  2 siblings, 1 reply; 116+ messages in thread
From: Robert Dewar @ 1999-05-24  0:00 UTC (permalink / raw)


In article <t7lneeqlzf.fsf@calumny.jyacc.com>,
  Hyman Rosen <hymie@prolifics.com> wrote:
> Could you give an example of this? I ask, because recently
Richard
> D. Riehle made a similar type of claim, and then declined to
post an
> example. I believe that many posters to this group are very
proficient
> in Ada but not as proficient in C++, so they may be mistaken
about
> what is difficult to do in C++. Posting an example allows
proficient
> C++ users to examine the apparently difficult code and offer
> alternatives.

Well obviously the case of extending an algebra that implements
symmetrical binary operators is a case more easily handled in
Ada than in C, I assume a specific example is not needed here?
But presumably you are looking for different kinds of things?

> (Note that I am not looking for arbitrary examples of where
Ada is
> better than C++. I know that Ada is better, for example, in
defining
> data storage layout that conforms to external specifications,
while
> C++ is better in providing automatic generic instantiation.)

Actually these two examples are not at all comparable. The
ability to declare data storage layout is a fundamental
functionality feature.

Automatic generic instantiation is a mechanism, which one may
or may not like. You can't really say that C++ is better in
this department if your viewpoint is that automatic generic
instantiation is a risky feature! So it is better to find
examples of fundamental functionality rather than mechanisms.

Of course the discussion about OO features is entirely
about mechanisms!


--== Sent via Deja.com http://www.deja.com/ ==--
---Share what you know. Learn what you don't.---




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

* Re: Ada OO Mechanism
  1999-05-20  0:00 ` Samuel Mize
  1999-05-20  0:00   ` David Botton
@ 1999-05-24  0:00   ` Hyman Rosen
  1999-05-24  0:00     ` Robert Dewar
                       ` (2 more replies)
  1 sibling, 3 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-24  0:00 UTC (permalink / raw)


Samuel Mize <smize@imagin.net> writes:
> There are other OO design approaches that are harder to implement in
> C++ than in Ada, because C++ strongly supports one specific view of
> object-oriented technology.

Could you give an example of this? I ask, because recently Richard
D. Riehle made a similar type of claim, and then declined to post an
example. I believe that many posters to this group are very proficient
in Ada but not as proficient in C++, so they may be mistaken about
what is difficult to do in C++. Posting an example allows proficient
C++ users to examine the apparently difficult code and offer
alternatives.

(Note that I am not looking for arbitrary examples of where Ada is
better than C++. I know that Ada is better, for example, in defining
data storage layout that conforms to external specifications, while
C++ is better in providing automatic generic instantiation.)




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

* Re: Ada OO Mechanism
  1999-05-24  0:00     ` Robert Dewar
@ 1999-05-24  0:00       ` Hyman Rosen
  1999-05-24  0:00         ` David Starner
  1999-05-24  0:00         ` Mike
  0 siblings, 2 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-24  0:00 UTC (permalink / raw)


Robert Dewar <robert_dewar@my-dejanews.com> writes:
> Well obviously the case of extending an algebra that implements
> symmetrical binary operators is a case more easily handled in
> Ada than in C, I assume a specific example is not needed here?

Actually, I would like a specific example - I don't understand
"an algebra that implements symmetrical binary operators" or
why it's easier in Ada. I'm not being difficult here - I really
just don't understand the meaning of the quoted phrase, so a
bit of actual code would go a long way to clarify things.

> But presumably you are looking for different kinds of things?

I posted the request in response to the claim that Ada allows certain
object-oriented techniques that are more difficult to express in C++.
I would like to see a bit of code demonstrating this, to determine to
my own satisfaction whether it's really true, or whether the Ada
poster doesn't know enough C++ to realize that it's easy there as
well.




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

* Re: Ada OO Mechanism
  1999-05-24  0:00       ` Hyman Rosen
@ 1999-05-24  0:00         ` David Starner
  1999-05-24  0:00           ` bob
  1999-05-24  0:00         ` Mike
  1 sibling, 1 reply; 116+ messages in thread
From: David Starner @ 1999-05-24  0:00 UTC (permalink / raw)




Hyman Rosen wrote:
> 
> Robert Dewar <robert_dewar@my-dejanews.com> writes:
> > Well obviously the case of extending an algebra that implements
> > symmetrical binary operators is a case more easily handled in
> > Ada than in C, I assume a specific example is not needed here?
> 
> Actually, I would like a specific example - I don't understand
> "an algebra that implements symmetrical binary operators" or
> why it's easier in Ada. I'm not being difficult here - I really
> just don't understand the meaning of the quoted phrase, so a
> bit of actual code would go a long way to clarify things.

Think of vectors and the dot product. C++ forces you to view one vector
as significant (a becomes "this" inside dot function, it's called
a.dot(b)), even though in a dot b, a and b are equal significance - dot
product is a symmetric function. Ada makes them of equal importnatce in
the dot function body and call.




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

* Re: Ada OO Mechanism
  1999-05-24  0:00           ` bob
@ 1999-05-24  0:00             ` David Starner
  1999-05-25  0:00               ` Ole-Hjalmar Kristensen
  0 siblings, 1 reply; 116+ messages in thread
From: David Starner @ 1999-05-24  0:00 UTC (permalink / raw)




bob wrote:
> 
> In article <3749E9EC.2842436A@aasaa.ofe.org>, David says...
> >
> 
> >Think of vectors and the dot product. C++ forces you to view one vector
> >as significant (a becomes "this" inside dot function, it's called
> >a.dot(b)), even though in a dot b, a and b are equal significance - dot
> >product is a symmetric function. Ada makes them of equal importnatce in
> >the dot function body and call.
> 
> Are sure you are not talking about Java (which does not have user defined
> operators) ?
Yes. I was discussing a.dot(b) vs. dot(a,b), not user defined operators.
> 
> You have to do the above in Java 'a.dot(b)'
> 
> but in C++, (unless '.' is one of those few things that are not
> allowed to be redefined), I can write 'a.b' just fine, why not?

First, I don't believe . is allowed to be redefined. Second, "." is not
the dot product dot (which I can't represent in ASCII.) Third,
redefining "." is evil - "." in C++ is a synatic element, not a
multiplicitave operator, and changing that is going to really confuse
any reader of the code.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                       ` Hyman Rosen
@ 1999-05-25  0:00                         ` Samuel Mize
  1999-05-25  0:00                           ` Chris
  1999-05-25  0:00                         ` Brian Rogoff
                                           ` (3 subsequent siblings)
  4 siblings, 1 reply; 116+ messages in thread
From: Samuel Mize @ 1999-05-25  0:00 UTC (permalink / raw)


I'm combining responses to two messages here.

Hyman Rosen <hymie@prolifics.com> wrote:
>Samuel Mize <smize@imagin.net> writes:
>> THE QUESTION: how does one do "mix-in" classes in C++?  I'd bet a
>> nickel that you can, but I don't know the specific mechanism.

Then you answered the question.  Thanks; I figured one could do it.

I'm using lines of "- " to separate major sections.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - The class is the primary form of data encapsulation.
>
>Classes support static data and function members, and nested classes.
>I believe that this gives C++ the equivalent of Ada's packages.

The difference is that, in Ada, encapsulation is distinct from the
object-oriented notion of "class."  Certainly a C++ class provides
encapsulation.  It also provides more, and this may cause confusion
when you want to encapsulate something without indicating that it
meets the OO notion of a "class."

There may be object-oriented approaches that uses this distinction,
but I don't have a reference handy, and I don't make this claim.

I do know that this distinction is extremely useful in a mixed-method
environment, e.g., object-oriented and procedural elements working
together.

That doesn't directly address "an OO method that's harder in C++."

It does point out that an OO/procedural integrated system may be less
clear in C++, as the reader must determine which classes are classes,
and which classes are not classes but just encapsulations of
non-class entities.  So, if we consider mixed-method programming to
be a form of OO, we can argue that this is a form of OO that is not
as well supported by C++ as by Ada.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - Each "message" (implemented as a dispatching function call) goes
>>   to exactly one object (or class).  Any other objects mentioned are
>>   passive arguments.
>
>How is this different from Ada? Does Ada allow dispatching on more than
>one argument?

Yes, see my other message.  As you noted in reply to it:

>Samuel Mize <smize@imagin.net> writes:
>>   -- This dispatches on both parameters, so they have to match
>>   -- at run-time
>>   procedure Operation_4 (A: A_Type; B: B_Type);
>
>(Do you mean B: A_Type ?)

Also, to your question:

>When you say "match at runtime" do you mean that their dynamic types
>must be the same? Does the code raise an exception if they happen not
>to match?

I'll detail this for you in a while, but I need to refer back to the ARM
and bone up first.

>If I were to code this in C++, I could do the following:
>
>   void Operation_4(A_Type &A, A_Type &B)
>   {
>      if (typeid(A) != typeid(B))
>         throw "Mismatched types!";
>      A.Operation_4(B);
>   }

You can manually code it up, but that doesn't mean the language
supports it -- rather the reverse.  By a similar argument, one can
claim to do full-up object-oriented programming in C.  Indeed, the
X-windows system is done that way (or used to be, anyway -- I haven't
looked at it for a few years).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - When an object sends a message, it waits for the called object
>>   to complete its processing of the message (that is, for the return
>>   of the function call) before continuing.
>> - One thread of control calls all objects; they are not independent
>>   active entities.
>
>Well, no argument there. C++ does not have a language-defined parallel
>processing capability, and Ada is absolutely superior in that regard.
>However, I would say that this is generally considered orthogonal to
>object-oriented programming, since your statement above is equally true
>if you replace objects and messages with plain function calls.

There are object-oriented methods of analysis and design that view
all the objects in a system as inherently parallel, independent
actors.  This is called the Actor model, and there are languages that
encapsulate it.  In this method, parallel independent execution is
not orthogonal to object-oriented programming; the method considers
independence of execution to be integral to their definition.

I don't say that OO programming inherently includes parallelism.  I
do say that there exist methods of OO programming which consider
parallelism integral to the definition of an object.  

>I think including parallel behavior in your definition
>of OO is stretching that definition beyond any accepted usage.

My assertion was that there are OO methods that are harder to implement
in C++ than in Ada.  Here is an example.  The fact that single-thread
OO methods don't consider parallelism to be integral to the concept of
"objects" does not invalidate other method that do.

It isn't as popular as the C++ model, as I said.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> Did you intend that paragraph to sound contentious?  To my ear,
>> at least, it has rather a "you're all liars, I'm naming names"
>> sound to it -- I hope that isn't what you meant.
>
>I wanted it to sound somewhat contentious. The named people each
>claimed ...
>There were responses, but no code, so I got a little testy.

Well, that's too bad.

There is a class of people (in Ada terms, a type :-) called a
net.loon.  I don't think you are one.

But one thing that net.loons often do is to demand that some other
poster provide hard evidence, right away, in whatever form they deem
most appropriate, to support some stray comment.

When the evidence doesn't show up on demand, the net.loon's next step
is to demand that the other poster publicly admit not only that they
might be mistaken, but that they were out-and-out lying and knew it.
Following this come other accusations, obscenities, and sometimes mail
bombs and other electronic harassment.

I think you can see why people would just ignore or kill-file anyone
who seems to be starting down that road with them.

So I would strongly suggest that you take a more "chilled out"
approach in posting.  Understand that people may hold and express
opinions without having statistics or code examples handy to support
them.  They may even hold and express opinions with nothing behind
them but hot air, and that's perfectly OK on the net.

They may also not see your question for days, if at all.  News
propagation can be unreliable.

And, most of us have lots of other things to do, like making a
living and living a life, and digging up specifics for a net argument
is way down on our list of priorities.

Especially when someone focuses in on one sentence out of a 175-line
post, ignores the rest of it, and bears down demanding hard evidence;
and after a couple of days, starts throwing my name around in another
post as one of Those People who didn't deliver evidence on demand.

And that's about as contentious as I want to get on the net.  I
hope to have fruitful and pleasant discussions with you in the future.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                         ` Samuel Mize
@ 1999-05-25  0:00                           ` Chris
  1999-05-25  0:00                             ` David Botton
  1999-05-27  0:00                             ` Samuel Mize
  0 siblings, 2 replies; 116+ messages in thread
From: Chris @ 1999-05-25  0:00 UTC (permalink / raw)


In article <7if7oj$bee@news1.newsguy.com>, Samuel says...
>
 
>
>I do know that this distinction is extremely useful in a mixed-method
>environment, e.g., object-oriented and procedural elements working
>together.
>

I don't think it leads to clear design when one part of the
program is done in OO ways, while another part is not.

one either uses all OO, or all procedural.

don't you agree?

Chris
 





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

* Re: Ada OO Mechanism
  1999-05-25  0:00                       ` Hyman Rosen
  1999-05-25  0:00                         ` Samuel Mize
@ 1999-05-25  0:00                         ` Brian Rogoff
  1999-05-25  0:00                           ` Jim
  1999-05-26  0:00                           ` Robert Dewar
  1999-05-25  0:00                         ` Richard D Riehle
                                           ` (2 subsequent siblings)
  4 siblings, 2 replies; 116+ messages in thread
From: Brian Rogoff @ 1999-05-25  0:00 UTC (permalink / raw)


On 25 May 1999, Hyman Rosen wrote:
> Samuel Mize <smize@imagin.net> writes:
> 
> ... snip ...
>
> > Did you intend that paragraph to sound contentious?  To my ear,
> > at least, it has rather a "you're all liars, I'm naming names"
> > sound to it -- I hope that isn't what you meant.
> 
> I wanted it to sound somewhat contentious. The named people each
> claimed in a posting that there were object-oriented techniques
> that were harder, or less elegant, in C++ than in Ada. I asked
> for examples with the thought that perhaps the posters didn't know
> C++ as well as they knew Ada, and were therefore perhaps mistaken.
> There were responses, but no code, so I got a little testy.

I think its true that a lot of people have had this discussion a few times 
on c.l.a., so when someone mentions symmetric binary operators they
imagine you've RTFM, or in this case the programming language FAQ, or the 
Rationale, or what have you. 

If you're interested in some other cases where the Ada mechanism is a
little nicer, there are lots of examples of dispatching on function result
that are easier, IMO of course, than the approaches in C++. Check out 

http://www.adahome.com/FAQ/programming.html#constructors
http://stwi.weizmann.ac.il/g-cs/benari/articles/func.htm

for examples. 

Another thing is that unless I'm missing something, C++ does not provide 
constrained genericity so you have to use workarounds like that in 

http://lazy.ton.tut.fi/~esap/instructive/simulating-constrained-genericity.html

so your example Ada code that you wrote in another message is in fact a
good example of a case where Ada is nicer :-)

Incidentally, I tend to agree with you about automatic instantiation, and
that was also discussed here. I tend to think that it shortens the code 
by eliminating noise instantiations, at least in quite a few examples I've
seen. There are a number of things I like better about C++, though I think 
my "ideal" systems programming language would look mostly like Ada. 

-- Brian






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

* Re: Ada OO Mechanism
  1999-05-25  0:00                         ` Brian Rogoff
@ 1999-05-25  0:00                           ` Jim
  1999-05-26  0:00                           ` Robert Dewar
  1 sibling, 0 replies; 116+ messages in thread
From: Jim @ 1999-05-25  0:00 UTC (permalink / raw)


folks: found this related to this topic. from adahome:

"
(Robb Nebbe responds) 

Offhand I can think of a couple of advantages arising from 
Ada's separation of the concepts of type and module. 

Separation of visibility and inheritance allows a programmer 
to isolate a derived type from the implementation details of its 
parent. To put it another way information hiding becomes a design 
decision instead of a decision that the programming language has 
already made for you. 

Another advantage that came "for free" is the distinction between 
subtyping and implementation inheritance. Since modules and types 
are independent concepts the interaction of the facilities for 
information hiding already present in Ada83 with inheritance provide 
an elegant solution to separating subtyping from implementation 
inheritance. (In my opinion more elegant than providing multiple 
forms of inheritance or two distinct language constructs.) "
 





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

* Re: Ada OO Mechanism
  1999-05-21  0:00 ` Dale Stanbrough
  1999-05-20  0:00   ` bob
  1999-05-21  0:00   ` Richard D Riehle
@ 1999-05-25  0:00   ` Don Overheu
  2 siblings, 0 replies; 116+ messages in thread
From: Don Overheu @ 1999-05-25  0:00 UTC (permalink / raw)


I have just caught up with Tucker Taft's response to this thread
querying the speed of Ada95. In his gentle way he suggests that the
pixel display is to blame for any perceived slowness in running a
Mandelbrot example. Perhaps what he was saying was that the problem
may resides in the operating system or the underlying hardware not the
Ada95 program or C. I happen to have Jerry Van Dijk's Mandelbrot example

to run under DOS. It is almost identical to Tucker Taft's example. I
have
recompiled it for Jerry's Adagraph to run under Win95. Here are the
results.

DOS: Screen size 640 by 480, run time 5 secs

Win95: Adagraph Screen size set to 640 by 480, run time 80 secs
       (that is not a misprint!). With pixel plotting removed as
       suggested by Tucker Taft, run time is 5 secs

 Equipment: 300Mh Pentium II Celeron, 65Mb RAM, 4Mb video card and 4Gb
            hard disc
Don Overheu





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

* Re: Ada OO Mechanism
  1999-05-24  0:00         ` Mike
@ 1999-05-25  0:00           ` Robert Dewar
  0 siblings, 0 replies; 116+ messages in thread
From: Robert Dewar @ 1999-05-25  0:00 UTC (permalink / raw)


In article <7icota$1fdh@drn.newsguy.com>,
  Mike  <Mike@newsguy.com> wrote:
> Prof. Dewar is not adopt to giving examples. He likes to give
> theories, but not examples, that is why he is a prof. :)

I often give examples where they are new and instructive. This
is such a well known example, which has been beaten to death
in previous threads, that it hardly seems worthwhile.

Part of the trouble with CLA is that it tends to recycle old
threads as new people join the discussion, but that can be
quite time wasting!

The issue with binary operators in tagged types is quite
fundamental. I refer anyone interested in this issue to
read the Ada 95 rationale, which addresses it.


--== Sent via Deja.com http://www.deja.com/ ==--
---Share what you know. Learn what you don't.---




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

* Re: Ada OO Mechanism
  1999-05-21  0:00       ` Richard D Riehle
@ 1999-05-25  0:00         ` Shawn M. Root
  0 siblings, 0 replies; 116+ messages in thread
From: Shawn M. Root @ 1999-05-25  0:00 UTC (permalink / raw)



Richard D Riehle wrote in message
<7i4brh$hi2@dfw-ixnews8.ix.netcom.com>...
:In article <7i2pqn$qak$1@news.orbitworld.net>,
: "Shawn M. Root" <smroot@orbitworld.net> wrote:
:
:>:So when I hear someone say that Ada is
:>:counterintuitive or C++ is counterintuitive or Object COBOL is
:>:counterintuitive, I understand that they mean, "This is not the way
:>:I am used to thinking about things."   That does not mean it is
:>:counterintuitive.  It simply means they have had difficulty learning
:>:a new programming language just as they might have trouble learning
a
:>:new spoken language.  When I hear someone speak of "natural"
language,
:>:I have to wonder what they are talking about.
:>:
:>Actually it does mean that it is counterintuitive.  Counterintuitive
:>means that what you found is not what you expected to find.  This is
a
:>relative term, not an absolute.  What is counterintuitive for me, may
:>be readily obvious to you.  Intuition has nothing to do with
"thinking
:>about things".
:
: I wonder if I want someone writing software for a pacemaker who is
: not "thinking about things."


Of course you don't.  Neither do I.

:  Intuition strikes me as a psychological
: concept that implies that one is "thinking about things" differently
: than through the use of more ordinary reasoning.

Perhaps this will help.
http://www.m-w.com/dictionary.htm

: I am willing to
: accept the notion of intuition as an important element of problem
: solving.

Exactly right.  It is _only_ an element in problem solving; not the
means to a complete solution.

<snip>

:
:>It has to do with the understanding or knowing of
:>something _without_ overt reasoning.  Furthermore, it does not mean
:>that someone had difficulty learning a new programming language.  It
:>simply means that, in my particular case, the Ada OO mechanisms seem
:>less obvious than the C++ mechanisms.
:
: The fact that some idea is not obvious makes it counterintuitive?
That
: notion, in itself, should make one suspicious of any effort to reach
: a conclusion by declaring that this or that is counterintuitive.

Again, I have to agree with you.  Noting that something is
counterintuitive may raise a question, but should not provide a
conclusion.

<snip>
:
: I do not believe one should become too comfortable with the notion of
: counterintuitive as an excuse for failure to learn some new idea.  In
: such cases, the failure may be that of the learner, not of the idea.

True.  In fact, questioning _why_ the idea is counterintuitive may
bring about a deeper understanding of both the new and older, related
ideas.  This was the intent of my original post.  I just want to
understand why tagged types were used instead of the seemingly more
popular class structure.


:>
:>Yes, but after calculus was invented, and the concept of the limit
was
:>understood, would you invent a new way to do limits if the new way
:>offered no significant advantages over the old way?
:
: The notion of limit did occur to earlier mathematics. It was simply
: not adopted, perhaps because it was counterintuitive.  If you have
: watched young freshman struggle with calculus, even today, the idea
: of limit still remains counterintuitive for many of them.
:

Perhaps I should have said "adopted" then, instead of "understood." The
question remains.


:>
:>Again, I don't know where you got this impression.  Perhaps others
:>you've spoken to have used the "counterintuitive excuse" to cover
:>difficulties in learning.  However, that is not the case here.  I was
:>introduced to Ada before C++ so, if anything, I had more trouble
:>learning the C++ way of doing things.  My comments have nothing to do
:>with not working hard enough to understand certain ideas.  I
understand
:>the ideas and concepts involved.  I understand the other side's
:>arguments.  So far, however, I don't agree with them.
:
: Perhaps it depends on where one stands to examine the issues.
Certainly,
: it is depends on what _arbitrary_ foundations one selects to support
: the argument.  When I look at a pencil immersed in water, it is clear
: to me that the pencil becomes bent.  Unless I understand some
additional
: physics, I will not realize that the pencil is not actually bent,
: even though it seems so obvious from my simple viewpoint that it is.
:

True, but how often do you need to know the physics?  If I'm building a
house, I don't need to know that a boards solidity is a result of an
interplay of forces between widely spaced atoms.  I just need to know
that if I nail it to this other board, it will stay there.

: It seems to me that, when evaluating software tools and languages, we
: need a more comprehensive view of the problem, one that does not
reject
: some perfectly good approach by suggesting that some starting point
for
: a solution seems counterintuitive.

Fine.  Then the comprehensive solution should not dismiss out of hand
the fact that an approach seems counterintuitive.  Most definitely not
in a language which has as one of it's goals, readability.

: It is often the intuition on which
: the counterintuitive conclusion is based that makes the
counterintuitive
: viewpoint the best place to begin looking for a solution.
: If Ada is
: counterintuitive, perhaps that is a good thing, especially when
seeking
: solutions to problems of designing large-scale, safety-critical
software.
:

I'm not sure how a counterintuitive language is supposed to promote
better design.  That said, I really don't think that Ada is
counterintuitive.  It is a very natural feeling language.  I just have
issues with why the tagged type was used instead of a class construct.
Since my original post, I have had conversations (sometimes loud) with
one of our local Ada experts.  He has given me many reasons why tagged
types were used instead of a class.  Samuel Mize's post was also very
illuminating.  They have at least left me reassured that the choice
wasn't entirely arbitrary.  It is disheartening, however, since I
believe that this could hurt Ada's chances for increased popularity.
It would be nice to see more and varied use of Ada.  The response I
received to my question was also a bit disheartening.  With the
exception of Mr. Mize, whose response was very helpful, I received no
other answers to my questions. Perhaps I would've gotten better results
with a "How do I send text to the screen?" question.

--
Shawn M. Root








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

* Re: Ada OO Mechanism
  1999-05-24  0:00             ` David Starner
@ 1999-05-25  0:00               ` Ole-Hjalmar Kristensen
  1999-05-25  0:00                 ` Florian Weimer
  1999-05-25  0:00                 ` Mark A Biggar
  0 siblings, 2 replies; 116+ messages in thread
From: Ole-Hjalmar Kristensen @ 1999-05-25  0:00 UTC (permalink / raw)


David Starner <dstarner98@aasaa.ofe.org> writes:

> bob wrote:
> > 
> > In article <3749E9EC.2842436A@aasaa.ofe.org>, David says...
> > >
> > 
> > >Think of vectors and the dot product. C++ forces you to view one vector
> > >as significant (a becomes "this" inside dot function, it's called
> > >a.dot(b)), even though in a dot b, a and b are equal significance - dot
> > >product is a symmetric function. Ada makes them of equal importnatce in
> > >the dot function body and call.
> > 
> > Are sure you are not talking about Java (which does not have user defined
> > operators) ?
> Yes. I was discussing a.dot(b) vs. dot(a,b), not user defined operators.
> > 

What makes you think you cannot implement dot(a,b) in C++?

<stuff deleted>
-- 
E pluribus Unix




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

* Re: Ada OO Mechanism
  1999-05-25  0:00               ` Ole-Hjalmar Kristensen
  1999-05-25  0:00                 ` Florian Weimer
@ 1999-05-25  0:00                 ` Mark A Biggar
  1999-05-25  0:00                   ` Hyman Rosen
  1 sibling, 1 reply; 116+ messages in thread
From: Mark A Biggar @ 1999-05-25  0:00 UTC (permalink / raw)


Ole-Hjalmar Kristensen wrote:
> 
> David Starner <dstarner98@aasaa.ofe.org> writes:
> 
> > bob wrote:
> > >
> > > In article <3749E9EC.2842436A@aasaa.ofe.org>, David says...
> > > >
> > >
> > > >Think of vectors and the dot product. C++ forces you to view one vector
> > > >as significant (a becomes "this" inside dot function, it's called
> > > >a.dot(b)), even though in a dot b, a and b are equal significance - dot
> > > >product is a symmetric function. Ada makes them of equal importnatce in
> > > >the dot function body and call.
> > >
> > > Are sure you are not talking about Java (which does not have user defined
> > > operators) ?
> > Yes. I was discussing a.dot(b) vs. dot(a,b), not user defined operators.
> > >
> 
> What makes you think you cannot implement dot(a,b) in C++?

You can, but there are some problems with doing that.

1) It's not really part of the class as it has to be defined as 
an external "friend" function.

2) It therefore CANNOT be made virtual so you can't dispatch on it.

3) This also greatly complicates its use in generic (template) algorithms.

None of those problems exist in Ada.

--
Mark Biggar
mark.a.biggar@lmco.com




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

* Re: Ada OO Mechanism
  1999-05-24  0:00   ` Hyman Rosen
  1999-05-24  0:00     ` Robert Dewar
@ 1999-05-25  0:00     ` Samuel Mize
  1999-05-25  0:00       ` Hyman Rosen
  1999-06-03  0:00     ` Matthew Heaney
  2 siblings, 1 reply; 116+ messages in thread
From: Samuel Mize @ 1999-05-25  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> wrote:
> Samuel Mize <smize@imagin.net> writes:
>> There are other OO design approaches that are harder to implement in
>> C++ than in Ada, because C++ strongly supports one specific view of
>> object-oriented technology.
> 
> Could you give an example of this?

I confess that I can't just pop up an example.  My non-C++ and
non-Ada object-oriented systems was (good grief) over a decade ago,
and I'm not all the way up the learning curve in C++.

Let me try to get someone else involved who will (I think) be able
to give you a better answer, ask you a question, and give you a
"reasonable" argument to consider.  I grant that this is weak.

THE SOMEONE ELSE is a frequent poster here, but I don't want to
drag him into a thread if he's intentionally ignoring it.  I'll email
him a copy of this posting.  He has said that he does object-oriented
development, but that he does not prefer the C++ model.  I have to
assume he routinely does things that don't fit well into that model.
I hope he will discuss (or give a pointer to previous discussion)
what method he prefers, and why it is incompatible with C++.

THE QUESTION: how does one do "mix-in" classes in C++?  I'd bet a
nickel that you can, but I don't know the specific mechanism.  The
"mix-in" metaphor is described in the Ada 95 Rationale, 4.6.2.

THE "REASONABLE" ARGUMENT: C++ supports a very specific view of
object-oriented development.  I'll list several things that I
believe are true about C++ (feel free to correct errors).  Each
of them represents a methodology decision.  Perfectly good methods
can be derived where each or all of these is false.  In that case,
C++ would not support that method well.

- The class is the primary form of data encapsulation.  (I have
  seen C++ advocates argue that Ada is weak because it provides
  encapsulation outside classes.)

- Each "message" (implemented as a dispatching function call) goes
  to exactly one object (or class).  Any other objects mentioned are
  passive arguments.

- When an object sends a message, it waits for the called object
  to complete its processing of the message (that is, for the return
  of the function call) before continuing.

- One thread of control calls all objects; they are not independent
  active entities.

Now, all reasonable languages are Turing-equivalent.  I'm sure one
could create, in C++, a system where all the objects are active
and objects send each other messages without waiting for a response;
or, one where several objects can work together co-equally to handle
some messages; or one where object-level messages go to a queue in
the object's class, and whatever object becomes free handles the
next message from the queue.  But each of these would be working
against the object-oriented model built into the language.

With Ada, one can do these things without working against the OO model
of the language, because the OO model is more general.  On the other
hand, for work within the OO model of C++, you don't have as much
method-specific support built into the language.  On the other other
hand, it's fairly easy to define a method in Ada where one gets a very
C++ "feel."  Mandate that every tagged type will be defined in its own
library-level package, with nothing in that package except for the
tagged type and its supporting class-level elements; every potentially
dispatching subprogram must have a controlling first parameter.  Voila,
C++ style!  The package is the equivalent of the "class" in C++.

I'm not saying that C++ is "lesser," "worse" or "wrong," I'm just saying
that it takes a different, but equally valid, design approach.  The
same is true for Ada.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                   ` Hyman Rosen
  1999-05-25  0:00                     ` Richard D Riehle
@ 1999-05-25  0:00                     ` Samuel Mize
  1999-05-25  0:00                       ` Hyman Rosen
  1999-05-28  0:00                     ` Robert I. Eachus
  1999-06-03  0:00                     ` Matthew Heaney
  3 siblings, 1 reply; 116+ messages in thread
From: Samuel Mize @ 1999-05-25  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> wrote:
> So you mean in Ada, I can write a dot(a,b) which will dispatch on
> either a or b?

Yes.  Either can be controlling.  If both are controlling, they both
have to be of the same type (the same class in C++ terms).

[uncompiled example]

  type A_Type is tagged with null record;

  -- All of these dispatch on A if it's a dispatching call

  procedure Operation_1 (A: A_Type; I: Integer);

  procedure Operation_2 (I: Integer; A: A_Type);

  procedure Operation_3 (A: A_Type; B: A_Type'Class);

  -- This dispatches on both parameters, so they have to match
  -- at run-time

  procedure Operation_4 (A: A_Type; B: B_Type);


> Once again, I will ask for an example demonstrating this, where
> something is more complicated to use in C++ generics than in Ada.
> This will make you the fourth person I have asked for this type
> of example, the others being Richard D. Riehle, Samuel Mize, and
> Robert Dewar. None of the others have chosen to post such an
> example.

Not instantly.  I did address this to the best of my ability in
another message, just today.  I'll grant that I don't have a code
example handy, and I'll grant that I was repeating "conventional
wisdom" from the group.

Did you intend that paragraph to sound contentious?  To my ear,
at least, it has rather a "you're all liars, I'm naming names"
sound to it -- I hope that isn't what you meant.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                   ` Hyman Rosen
@ 1999-05-25  0:00                     ` Richard D Riehle
  1999-05-25  0:00                       ` David Botton
  1999-05-27  0:00                       ` Aidan Skinner
  1999-05-25  0:00                     ` Samuel Mize
                                       ` (2 subsequent siblings)
  3 siblings, 2 replies; 116+ messages in thread
From: Richard D Riehle @ 1999-05-25  0:00 UTC (permalink / raw)


In article <t7iu9hrqpw.fsf@calumny.jyacc.com>,
	Hyman Rosen <hymie@prolifics.com> wrote:

>Once again, I will ask for an example demonstrating this, where
>something is more complicated to use in C++ generics than in Ada.
>This will make you the fourth person I have asked for this type
>of example, the others being Richard D. Riehle, Samuel Mize, and
>Robert Dewar. None of the others have chosen to post such an
>example.

 I have a wonderful little proof that this is the case but this
 margin is too narrow for me to write it in its entirety. To
 paraphrase G.B. Shaw, "One an lay all the language advocates
 in the world end to end and still not reach a conclusion."  

 There are certainly benefits to the C++ approach for generic
 programming, which is how Dr. Stroustrup refers to templates
 in his own book and how Ada refers to the same subject.  There
 are also benefits to the Ada approach.  There were inadequacies
 with the Ada model for generics before the addition of the 

            "with package ..."

 construct.  There were serious problems with C++ prior to adding
 the typename reserved word.  Both languages are evolving.  I prefer
 the Ada model for most designs.  However, the syntax of C++ is a
 little more straightforward.  The Ada syntax is designed to enforce
 a stricter set of type checking rules.  C++ can also, in most but not
 all, cases do strict type checking.  There are published examples of
 this.  One of my favorite columns is in a magazine, C++ Report, called
 "Obfuscated C++."  The monthly examples illustrate the central idea. 

 Take any of the examples from that column and try to create equally 
 obfuscated Ada.  In fact, try to create an "obfuscated" Ada program.
 Pretty difficult (not impossible).  

 I am not going to engage in dueling source code where anything I
 can play on my banjo you can play your guitar and Robert can play
 on his pipe organ.  On the other hand, Tocatta and Fuge in D Minor
 is a bit of a stretch for my banjo and Foggy Mountain Breakdown
 sounds a little strange on the pipe organ.  

 C++ is a great language for graphics and other stuff that is not
 safety-critical.  It would seem to me, strange, to select it as 
 the language for flight avionics, air traffic control, or other 
 projects where human life is at stake.  I know people do this, but
 knowing a little bit about both Ada and C++, I find it scary when
 someone decides to use C++ in this situation.  On the other hand,
 for high-speed graphics where safety is not a factor, C++ might ]
 often be a better choice than Ada.  Some instruments just do better
 for certain kinds of music.

 Richard Riehle
 richard@adaworks.com
 http://www.adaworks.com

 




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                       ` Hyman Rosen
  1999-05-25  0:00                         ` Samuel Mize
  1999-05-25  0:00                         ` Brian Rogoff
@ 1999-05-25  0:00                         ` Richard D Riehle
  1999-05-25  0:00                           ` Hyman Rosen
                                             ` (3 more replies)
  1999-05-27  0:00                         ` Samuel Mize
  1999-05-27  0:00                         ` Samuel Mize
  4 siblings, 4 replies; 116+ messages in thread
From: Richard D Riehle @ 1999-05-25  0:00 UTC (permalink / raw)


In article <t7675gswiv.fsf@calumny.jyacc.com>,
	Hyman Rosen <hymie@prolifics.com> wrote:

>I wanted it to sound somewhat contentious. The named people each
>claimed in a posting that there were object-oriented techniques
>that were harder, or less elegant, in C++ than in Ada. I asked
>for examples with the thought that perhaps the posters didn't know
>C++ as well as they knew Ada, and were therefore perhaps mistaken.
>There were responses, but no code, so I got a little testy.

OK.  There are hundreds of source code examples one could choose.  I
promised myself not to get into this any further, but it
just isn't to be. I am going to give just this one example illustrating
array management using Ada with the suggestion that Mr. Rosen post
some corresponding code in C++.  My apologies to those of you in the
Ada community who prefer to avoid these bladder-purging contests.

In C++ every array begins with an index of zero.  This makes 
array algorithms slightly more awkward than Ada.  Ada does not
assume that everything in the world begins with zero.  In C++,
this often results in "off by one" errors, all too easy to create,
all too difficult to debug in large programs. Of course, no 
intelligent programmer would make this mistake. ;)


Also, multiple dimension arrays in Ada may be declared as actual multiple 
dimension arrays as well as arrays of arrays.  I assume you know
C++ well, so will not bother to code each example in C++ except
where necessary.  Here are some Ada examples that are useful.
 
 Example One:

     type Float_32 is digits 6;  -- declare 32 bit float;
     for Float_32'Size use 32;   -- force size to 32 bits
     type Index is range -42..42;
     -- a constrained array type
     type Life_Universe_And_Everything is array(Index) of Float_32;
     Babel_Fish : Life_The_Universe_And_Everything;
  
     Now we might want to traverse this array from beginning to end. 
     Ada makes this quite easy.  Consider,

              for I in Babel_Fish'Range
                  loop
                     -- some computation
                  end loop;
 
     That is readable Ada.  Since you are the C++ expert, we leave
     it to you to supply a corresponding loop in C++, one that 
     processes an array with a negative index. 

 Example 2:

     Ada will permit us to declare an unconstrained array in which
     the index may be of any discrete type.  The index does not even
     have to be an integer.  We will, however, use an integer type
     type in this example.

     type My_Index is range - 2**12..2**12-1:  -- (-4096 .. 4095);
     type FourKarray is array(My_Index <>) of Float_32;

     The array is an unconstrained array.  Before we may use it, it
     must be constrained.  We may also call a function or procedure
     with an unconstained array and generalize the code quite nicely.

     
        The_Array : FourKarray(-3000..2000);
     
        procedure Process(Data : in out FourKarray) is   
        begin
           for I in F'Range 
              loop
                -- actions on array, F;
               end loop;
        end Process;

     We might call Process with X,

        Process(Data => The_Array); -- associate formal with actual

     Once again, you might supply C++ code for this algorithm and 
     the corresponding procedure call.

 Example 3:

     As mentioned earlier, Ada permits many techniques for 
     declaring and traversing multiple dimensional arrays.
     Here is an example that you might find interesting.

     type Month is (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sept,
                    Oct, Nov, Dec);
     type Day is range 1..31;

     type Day_Of_Month is array(Month, Day) of Boolean;

     Now we want to traverse the array with Month as the major
     index of our loop.

           for I in Day_Of_Month'Range(1)
                loop
                   for J in Day_Of_Month'Range(2)
                       loop
                           -- Do something to element of matrix
                           if some-condition then
                             Day_Of_Month(I, J) := True;
                           end if;
                       end loop;
                end loop;
     
        Notice that the enumerated type is an ordered set, unlike
        C++.  Also, there is no need to do any arithmetic on the
        enumerated type.  In the example shown, we are permitted
        to identify which dimension of the array is being processed
        by putting it in parentheses. Therefore, 'Range(2) refers
        to the second dimension.  This is handy if I decide to do 
        it differently.  Consider,

                for I in Day_Of_Month'Range(2)
                loop
                   for J in Day_Of_Month'Range(1)
                       loop
                           -- Do something to element of matrix
                           if some-condition then
                             Day_Of_Month(I, J) := True;
                           end if;
                       end loop;
                end loop;

   where we change the major and minor dimensions through a simple
   alteration of the 'Range(X) attribute.  Once again, you are
   challenged to provide corresponding code in C++.  

   I could many more more examples of array processing in 
   Ada that are simple, straightforward and easy to code.  One more
   important point;  the index to the array is a constant and only
   lives as long as the scope of the array.  In the current C++
   standard, the index also goes out of scope, but this was not always
   the case.  Some C++ compilers do not yet apply the current standard,
   and some permit the older code to still compile in the interest
   portability -- but at the expense of reliability.  More important,
   in C++ one can code a loop such as,

              for (i = 0; i < 10; i++)
                { // some code here
                     i = 10;
                }

which would be illegal in Ada for safey reasons.  In general, array and
matrix processing in Ada is so much superior to C++ that it makes 
me wonder why anyone would even raise a question about it.   It is not
unknown, in C++ programs, to have defects that result from simple
programming errors.  For example, has anyone ever coded i++ when they
intended ++i?  Will it make a difference in the behavior of the program?
Will the compiler even bother to give you a warning?  

On the other hand, we could find some illustrations where C++ does
certain things better than Ada.  That problme is left as an exercise
to the student.

Richard Riehle
richard@adaworks.com
http://www.adaworks.com

   
 
     
     
 




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

* Re: Ada OO Mechanism
  1999-05-25  0:00               ` Ole-Hjalmar Kristensen
@ 1999-05-25  0:00                 ` Florian Weimer
  1999-05-25  0:00                 ` Mark A Biggar
  1 sibling, 0 replies; 116+ messages in thread
From: Florian Weimer @ 1999-05-25  0:00 UTC (permalink / raw)


Ole-Hjalmar Kristensen <ohk@clustra.com> writes:

> What makes you think you cannot implement dot(a,b) in C++?

In C++, you won't get late binding (aka dynamic dispatching, aka virtual
methods) this way.  In Ada, you will.

You could provide some kind of wrapper function to obtain the same
effect in C++, but I think the Ada solution to this particular problem
(i.e. no need for a wrapper function) is clearly more elegant.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                 ` Mark A Biggar
@ 1999-05-25  0:00                   ` Hyman Rosen
  1999-05-25  0:00                     ` Richard D Riehle
                                       ` (3 more replies)
  0 siblings, 4 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-25  0:00 UTC (permalink / raw)


Mark A Biggar <mark.a.biggar@lmco.com> writes:
> 1) It's not really part of the class as it has to be defined as 
> an external "friend" function.

Friend functions and classes constitute parts of an interface.
Some people would like to criticize C++ both for "requiring that
everything be inside a class" and then again for using friends
"which are not part of the class". They merely, or willfully,
misunderstand the C++ model.

> 2) It therefore CANNOT be made virtual so you can't dispatch on it.

So you mean in Ada, I can write a dot(a,b) which will dispatch on
either a or b? I wasn't aware that this was the case. I actually
think that this is in fact *not* the case, in which case I have no
trouble writing a dispatching version in C++ either - just have
dot(a,b) call a.dot(b). In both Ada and C++, the apparent external
symmetry will then hide the internal asymmetry.

> 3) This also greatly complicates its use in generic (template) algorithms.
> None of those problems exist in Ada.

Once again, I will ask for an example demonstrating this, where
something is more complicated to use in C++ generics than in Ada.
This will make you the fourth person I have asked for this type
of example, the others being Richard D. Riehle, Samuel Mize, and
Robert Dewar. None of the others have chosen to post such an
example.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00     ` Samuel Mize
@ 1999-05-25  0:00       ` Hyman Rosen
  1999-05-25  0:00         ` David Starner
                           ` (2 more replies)
  0 siblings, 3 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-25  0:00 UTC (permalink / raw)


Samuel Mize <smize@imagin.net> writes:
> THE QUESTION: how does one do "mix-in" classes in C++?  I'd bet a
> nickel that you can, but I don't know the specific mechanism.  The
> "mix-in" metaphor is described in the Ada 95 Rationale, 4.6.2.

I believe this Ada --

   generic
      type S is abstract tagged private;
   package P is
      type T is abstract new S with private;
      -- operations on T
   private
      type T is abstract new S with
         record
            -- additional components
         end record;
   end P;

corrsponds to this C++ --

   template <typename S>
   class P
   {
   public:
      class T : public S
      {
      private:
         // additional components
      }
   };

and given some type A, one could declare objects of type P<A>::T.
These objects are derived from A and also implement the extra
operations of T. I haven't bothered to duplicate the 'abstract',
but that's easily done by giving T an abstract destructor, ~T() = 0.

> - The class is the primary form of data encapsulation.

Classes support static data and function members, and nested classes.
I believe that this gives C++ the equivalent of Ada's packages.

> - Each "message" (implemented as a dispatching function call) goes
>   to exactly one object (or class).  Any other objects mentioned are
>   passive arguments.

How is this different from Ada? Does Ada allow dispatching on more than
one argument?

> - When an object sends a message, it waits for the called object
>   to complete its processing of the message (that is, for the return
>   of the function call) before continuing.
> - One thread of control calls all objects; they are not independent
>   active entities.

Well, no argument there. C++ does not have a language-defined parallel
processing capability, and Ada is absolutely superior in that regard.
However, I would say that this is generally considered orthogonal to
object-oriented programming, since your statement above is equally true
if you replace objects and messages with plain function calls.

> I'm sure one could create, in C++
...
> But each of these would be working against the object-oriented model
> built into the language.

Instead, C++ programmers generally use third-party or system packages
which allow parallel processing. These have no impact upon the OO model
at all, and certainly don't forbid anything you might normally do. You
do have to be careful about protecting shared resources, but that's true
in Ada as well. I think including parallel behavior in your definition
of OO is stretching that definition beyond any accepted usage.

> I'm not saying that C++ is "lesser," "worse" or "wrong," I'm just saying
> that it takes a different, but equally valid, design approach.  The
> same is true for Ada.

To quote you,
  > There are other OO design approaches that are harder to implement in
  > C++ than in Ada, because C++ strongly supports one specific view of
  > object-oriented technology.

See? You said there are OO approaches that are harder to implement in C++
than in Ada. If you're talking about implementing parallel processing,
fine, I agree. Otherwise, I would like to see an example, so that I can
determine whether that's really true, or whether it comes from an
incomplete understanding of C++.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                     ` Samuel Mize
@ 1999-05-25  0:00                       ` Hyman Rosen
  1999-05-25  0:00                         ` Samuel Mize
                                           ` (4 more replies)
  0 siblings, 5 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-25  0:00 UTC (permalink / raw)


Samuel Mize <smize@imagin.net> writes:
>   -- This dispatches on both parameters, so they have to match
>   -- at run-time
>   procedure Operation_4 (A: A_Type; B: B_Type);

(Do you mean B: A_Type ?)

Thanks, this is the kind of example I meant! This is something that
C++ can't do by itself. When you say "match at runtime" do you mean
that their dynamic types must be the same? Does the code raise an
exception if they happen not to match?

If I were to code this in C++, I could do the following:

	void Operation_4(A_Type &A, A_Type &B)
	{
		if (typeid(A) != typeid(B))
			throw "Mismatched types!";
		A.Operation_4(B);
	}

The method Operation_4 of all subclasses of A_Type would have to be
written to take a paremeter of type A_Type, so it's not nearly as
nice as Ada, where I assume that this does not have to be the case.

> Did you intend that paragraph to sound contentious?  To my ear,
> at least, it has rather a "you're all liars, I'm naming names"
> sound to it -- I hope that isn't what you meant.

I wanted it to sound somewhat contentious. The named people each
claimed in a posting that there were object-oriented techniques
that were harder, or less elegant, in C++ than in Ada. I asked
for examples with the thought that perhaps the posters didn't know
C++ as well as they knew Ada, and were therefore perhaps mistaken.
There were responses, but no code, so I got a little testy.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                         ` Richard D Riehle
@ 1999-05-25  0:00                           ` Hyman Rosen
  1999-05-26  0:00                             ` Ray Blaak
       [not found]                           ` <t7zp2sr6yf.fsf@calumny.jyacc.c <t7emjmmx8w.fsf@calumny.jyacc.com>
                                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 116+ messages in thread
From: Hyman Rosen @ 1999-05-25  0:00 UTC (permalink / raw)


Richard D Riehle <laoXhai@ix.netcom.com> writes:
> In article <t7675gswiv.fsf@calumny.jyacc.com>,
> 	Hyman Rosen <hymie@prolifics.com> wrote:
> >I wanted it to sound somewhat contentious. The named people each
> >claimed in a posting that there were object-oriented techniques
> >that were harder, or less elegant, in C++ than in Ada.

...and follows up with code demonstrating the superiority of Ada
array handling over the C++ version.

I agree completely. Native Ada array handling beats the pants off
of native C++ array handling. Any equivalent I could produce in C++
would be longer, require custom classes, and be nowhere near as
nice.

Array indexing, however, does not normally fall under the heading
of object-oriented techniques.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00       ` Hyman Rosen
@ 1999-05-25  0:00         ` David Starner
  1999-05-26  0:00         ` Ole-Hjalmar Kristensen
  1999-05-26  0:00         ` Laurent Guerby
  2 siblings, 0 replies; 116+ messages in thread
From: David Starner @ 1999-05-25  0:00 UTC (permalink / raw)


Hyman Rosen wrote:
> > - The class is the primary form of data encapsulation.
> 
> Classes support static data and function members, and nested classes.
> I believe that this gives C++ the equivalent of Ada's packages.

Yes, but that approach is alien to C++, where as it's a natural approach
in Ada.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                     ` Richard D Riehle
@ 1999-05-25  0:00                       ` David Botton
  1999-05-26  0:00                         ` Tom Moran
  1999-05-27  0:00                       ` Aidan Skinner
  1 sibling, 1 reply; 116+ messages in thread
From: David Botton @ 1999-05-25  0:00 UTC (permalink / raw)


I don't find that the case at all and I don't think other here would
either.

See:
For an example of a freeware Ada 3D engine see Gautier's page:
http://members.xoom.com/gdemont/e3d.htm

I have already been playing around with Direct x and Direct 3D using my
COM binding generator and I have seen some fantastic simulations done in
Ada.

The Ada support for tasking and protected objects is exactly what makes
high speed complex graphics a great fit. Beyond that the very keen
ability to do concrete representations make it a very complete package.

What in C++ lends its self towards better graphics support?

David Botton



Richard D Riehle wrote:
>  On the other hand,
>  for high-speed graphics where safety is not a factor, C++ might ]
>  often be a better choice than Ada.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                           ` Chris
@ 1999-05-25  0:00                             ` David Botton
  1999-05-27  0:00                               ` Aidan Skinner
  1999-05-27  0:00                             ` Samuel Mize
  1 sibling, 1 reply; 116+ messages in thread
From: David Botton @ 1999-05-25  0:00 UTC (permalink / raw)


I find that the flexibility often lends itself to very clear designs.

Here and there I have been working on a cross platform set of GUI
classes. By combining a number of different methods of design I created
a very fluid and easy to use set of classes. (I will set up a project
page for the classes soon in the Ada Lab - http://www.adapower.com/lab
once I finish off a couple dead lines)

If Perl is the duct tape of programming languages, Ada is the Rambo
knife of engineering. (OK maybe swiss army fit better ...)

David Botton


Chris wrote:
> 
> In article <7if7oj$bee@news1.newsguy.com>, Samuel says...
> >
> 
> >
> >I do know that this distinction is extremely useful in a mixed-method
> >environment, e.g., object-oriented and procedural elements working
> >together.
> >
> 
> I don't think it leads to clear design when one part of the
> program is done in OO ways, while another part is not.
> 
> one either uses all OO, or all procedural.
> 
> don't you agree?
> 
> Chris
>




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                       ` David Botton
@ 1999-05-26  0:00                         ` Tom Moran
  0 siblings, 0 replies; 116+ messages in thread
From: Tom Moran @ 1999-05-26  0:00 UTC (permalink / raw)


>The Ada support for tasking and protected objects is exactly what makes
>high speed complex graphics a great fit.
Definitely.  My  first real Ada project involved video
capture/edit/playback and it was easy with separate video/audio/user
interaction tasks.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                         ` Brian Rogoff
  1999-05-25  0:00                           ` Jim
@ 1999-05-26  0:00                           ` Robert Dewar
  1999-05-26  0:00                             ` Brian Rogoff
  1 sibling, 1 reply; 116+ messages in thread
From: Robert Dewar @ 1999-05-26  0:00 UTC (permalink / raw)


In article
<Pine.BSF.4.10.9905252005460.2577-100000@shell5.ba.best.com>,
  Brian Rogoff <bpr@shell5.ba.best.com> wrote:
> Incidentally, I tend to agree with you about automatic
> instantiation, and that was also discussed here. I tend to
> think that it shortens the code

generally this is an invalid argument from the Ada point of
view, without additional justification that this shortening
makes it easier to *read* and *maintain* the code.

> by eliminating noise instantiations

If this really is noise, that does not help the maintainer of
the code, then that is indeed a fair point. However many people
feel (including me) that the explicit instantiations most often
are helpful to the maintainers of the code, and that implicit
instantiations, while allowing neat things to be written, can
generate code that is over-obscure.

As always, talking about generalities is usually useless, and
especially in a case like this, where it depends very much on
the specific case, we should really have a specific case to
talk about.


--== Sent via Deja.com http://www.deja.com/ ==--
---Share what you know. Learn what you don't.---




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                           ` Hyman Rosen
@ 1999-05-26  0:00                             ` Ray Blaak
  1999-05-26  0:00                               ` Hyman Rosen
  1999-05-26  0:00                               ` Richard D Riehle
  0 siblings, 2 replies; 116+ messages in thread
From: Ray Blaak @ 1999-05-26  0:00 UTC (permalink / raw)



Hyman Rosen <hymie@prolifics.com> writes:
> ...and follows up with code demonstrating the superiority of Ada
> array handling over the C++ version.
[...]
> Array indexing, however, does not normally fall under the heading
> of object-oriented techniques.

Well, here is an OO example showing difficulties with the C++ model as compared
to Ada. It is about a generic/template vector class with binary operators
involving scalars. In Ada, due to its method(obj,parm) notation, things are
declared in a straight forward way. In C++, friend procedures are required,
which is no suprise. The problem with C++, however, is that friend functions
cannot be implicitly instantiated when the vector class is instantiated.

Ada:

generic
   type ScalarType is (<>); -- Is this right? My Ada is rusty.
package Vector is
   type T is private;

   function Create(size : Natural) : T;

   function "*" (vector : in T; scalar : in ScalarType) : T;
   function "*" (scalar : in ScalarType; vector : in T) : T;
private
   -- whatever
end;

declare
   package IntVector is new Vector(Integer); 
   use type IntVector;
   package FloatVector is new Vector (Float); 
   use type FloatVector;

   I : IntVector.T := IntVector.Create(3);
   F : FloatVector.T := FloatVector.Create(3);
begin
   I := I*2;
   I := 2*I;
   F := F*2;
   F := 2*F;
end;


C++:

template <typename ScalarType>
class Vector
{
public:
  Vector (int size) { /* whatever */ };
  ~Vector() {};

  Vector operator* (ScalarType scalar)
  {return Vector(0); /* whatever */};

  friend Vector operator* (ScalarType scalar, Vector & V);
};

Vector<int> operator* (int scalar, Vector<int> & V)
{
  return V * scalar;
}

// later:

  Vector<int> I(3);
  I = I * 2;
  I = 2 * I;

  Vector<float> F(3);
  F = F * 2;
  F = 2 * F;

In this example, things won't link because I "forgot" to declare the
Vector<float> friend function. Not a big deal, since I can just do
it. However, it is tedious that I don't get what I need as soon as
Vector<float> is instantiated. I could make a mistake in defining it.

If one could have template namespaces, then maybe the class and friend
function could be defined together, but then one would have to switch to the
instantiated namespace (analogous to the "use type" in the Ada above, I
suppose).

The point is the C++ is a little more clumsy in this regard. If anyone has a
way to do the C++ example cleanly, I would be most interested, since I
currently use C++ in my projects. In particular, I was playing with defining
the friend function as:

template<typename ScalarType> Vector<ScalarType> operator*(...)
{...}

but couldn't get it to work.

-- 
Cheers,                                        The Rhythm is around me,
                                               The Rhythm has control.
Ray Blaak                                      The Rhythm is inside me,
blaak@infomatch.com                            The Rhythm has my soul.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00       ` Hyman Rosen
  1999-05-25  0:00         ` David Starner
@ 1999-05-26  0:00         ` Ole-Hjalmar Kristensen
  1999-05-26  0:00         ` Laurent Guerby
  2 siblings, 0 replies; 116+ messages in thread
From: Ole-Hjalmar Kristensen @ 1999-05-26  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:

> Samuel Mize <smize@imagin.net> writes:
> > THE QUESTION: how does one do "mix-in" classes in C++?  I'd bet a
> > nickel that you can, but I don't know the specific mechanism.  The
> > "mix-in" metaphor is described in the Ada 95 Rationale, 4.6.2.
> 
> I believe this Ada --
> 
>    generic
>       type S is abstract tagged private;
>    package P is
>       type T is abstract new S with private;
>       -- operations on T
>    private
>       type T is abstract new S with
>          record
>             -- additional components
>          end record;
>    end P;
> 
> corrsponds to this C++ --
> 
>    template <typename S>
>    class P
>    {
>    public:
>       class T : public S
>       {
>       private:
>          // additional components
>       }
>    };
> 
> and given some type A, one could declare objects of type P<A>::T.
> These objects are derived from A and also implement the extra
> operations of T. I haven't bothered to duplicate the 'abstract',
> but that's easily done by giving T an abstract destructor, ~T() = 0.
> 

In C++, you don't even need templates to do mix-in's. The following
method will work:

class a {
public:
        virtual void f() = 0;
};

class b: virtual public a {
public:
        void g(){ 
           ....
           f();
           ....
        }
};

class a_impl_1: virtual public a {
public:
        void f(){
                do_something();
        }
};

class a_impl_2: virtual public a {
public:
        void f(){
                do_something_else();
        }
};

class mixed1: public b, public a_impl_1{
};

class mixed2: public b, public a_impl_2{
};

Now, in mixed1, g will call a_impl_1::g(), and in mixed2, g will call
a_impl_2::g().
Any function which is virtual in class a is accessible to any derived
class, but the actual function which is called is determined at run
time. The classes which are derived from a has to declare a as a
virtual base class, or we would get multiple a's in mixed1 and mixed2,
and the mechanism would not work.


<stuff deleted>


-- 
E pluribus Unix




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

* Re: Ada OO Mechanism
  1999-05-26  0:00                           ` Robert Dewar
@ 1999-05-26  0:00                             ` Brian Rogoff
  0 siblings, 0 replies; 116+ messages in thread
From: Brian Rogoff @ 1999-05-26  0:00 UTC (permalink / raw)


On Wed, 26 May 1999, Robert Dewar wrote:
> In article
> <Pine.BSF.4.10.9905252005460.2577-100000@shell5.ba.best.com>,
>   Brian Rogoff <bpr@shell5.ba.best.com> wrote:
> > Incidentally, I tend to agree with you about automatic
> > instantiation, and that was also discussed here. I tend to
> > think that it shortens the code
> 
> generally this is an invalid argument from the Ada point of
> view, without additional justification that this shortening
> makes it easier to *read* and *maintain* the code.

Indeed, although I think it safe to say that if it didn't make it any 
*harder* to read and maintain code, that shortening wouldn't be a bad
idea. But that's academic, those factors are seldom (never?) orthogonal.

> > by eliminating noise instantiations
> 
> If this really is noise, that does not help the maintainer of
> the code, then that is indeed a fair point. However many people
> feel (including me) that the explicit instantiations most often
> are helpful to the maintainers of the code, and that implicit
> instantiations, while allowing neat things to be written, can
> generate code that is over-obscure.

The same thing can be said for overloading and use clauses too, though I
much appreciate overloading and use clauses and feel that used well they
leads to easier to read code. Automatic instantiation is in the same 
category IMO. 

> As always, talking about generalities is usually useless, and
> especially in a case like this, where it depends very much on
> the specific case, we should really have a specific case to
> talk about.

There are a few examples in the Tri-Ada '91 paper "Automatic Instantiation
in Ada". Note that the proposal there was an upward compatible extension
to Ada 83 which really just made some, not all, instantiations optional.
It is also unlike the C++ template mechanism in that it doesn't support 
things like template metaprogramming. If you look at any of the STL in 
Ada libraries, you'll also see examples of places where autoinstantiation 
would be nice. I'll cook up some examples for you, if you find the examples 
in the Tri-Ada paper unconvincing.

I certainly believe from my experiences doing STLish stuff in Ada that
such a mechanism would make that style of programming more convenient, and
by convenient here I mean for the reader as well as the writer. My
experience with ML also has a part in convincing me that a little bit of 
type inference is OK, though I think that explicit typing is best most of 
the time.

-- Brian






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

* Re: Ada OO Mechanism
  1999-05-26  0:00                             ` Ray Blaak
  1999-05-26  0:00                               ` Hyman Rosen
@ 1999-05-26  0:00                               ` Richard D Riehle
  1999-05-26  0:00                                 ` Hyman Rosen
  1 sibling, 1 reply; 116+ messages in thread
From: Richard D Riehle @ 1999-05-26  0:00 UTC (permalink / raw)



In response to my example showing array handling in Ada versus
C++, 

>Hyman Rosen <hymie@prolifics.com> writes:
>> ...and follows up with code demonstrating the superiority of Ada
>> array handling over the C++ version.
>[...]
>> Array indexing, however, does not normally fall under the heading
>> of object-oriented techniques.

 Yes, I suppose that is true.  Array management and implementation
 details of other container classes is more the province of programming
 than object-oriented programming.  However, someone once said, "The
 Devil is in the details."   Since part of this discussion began as
 a question regarding the C++ versus the Ada generic in OOP, perhaps
 it is instructive to note that the array example is not completely
 unrelated to the original quest, especially when one considers the
 details. 

 Nevertheless, the above point will not satisfy those with a need for
 more OO specific examples.  So I will take some time and return to
 my software greenhouse to grow some additional examples, especially
 since my email has explicitly encouraged me to continue the
 "bladder purging" contest.  

The examples will not appear instantaneously since I do have to devote
a small portion of my workday to actual work.  One idea that occurred
to me driving to work this morning was a nice feature of Ada that
allows me to overload a function based on return type and use that
return type as a controlling result for dispatching.  Also, the ability 
to create functions that return a classwide type.  The value of those
features could be lost on someone not familiar with Ada, but they serve
as powerful design mechanisms.

For example, in the same scope and visibility

         type T is tagged ...
 
         function Get(F : some-file) return T;
         function Get(F : access some-file) return T;
         function Get(F : some-file) return T'Class;

         type B is new T with ...

         function Get(F : some-file) return B;
         function Get(F : access some-file) return B;

         
 where the two type specific Get's are dispatching operations
 and the return type resolves the overloading.  This is not
 possible in C++ and it limits certain design decisions.  There
 are dozens of these kinds of examples.  It is interesting that
 this example also extends itself to the design of templates and
 makes Ada a little more flexible.

 One of the original contentions was that, although the C++ model of
 
             class <=> type <=> module

 appears to be simpler on the surface, as one begins to design large
 scale software, that model becomes something of a straightjacket. It
 utltimately requires friend functions and other encapsulation-breaking
 features (such as the new "mutable" reserved word) to get around the
 restrictions imposed by such a small model of object-oriented 
 programming.  

 On the positive side, this same model has been used by Eiffel more
 successfully than by C++.  This is probably because Eiffel did not
 begin with the need to counter side-effects inherited from C.  In 
 the new ISO C++ standard, many of those side-effects have been 
 eliminated by proscribing some of the more dangerous features of C.
 However, Java, C++ and Eiffel all fail to explicitly separate the
 contract from the implementation.  

 Separation of the contract from the implementation, while an option
 in C++, is not always desirable for technical reasons.  This separation
 of contract from implementation is a far more important feature for
 good object-oriented programming than making the class and type and 
 module the same unit.  

 I will try to create some coded examples in the coming week.  I hope 
 others will also contribute to this thread.  Even though the comparison
 of languages is often considered fruitless, I am beginning to believe
 it is important.  Why?

 More and more of our DoD clients are making the mistake of choosing C++
 instead of Ada for critical software.  I think it is important that
 such decisions be made on the basis of good information.  When the two
 languages are examined in depth, I have no doubt that an informed
 management would realize the benefits of Ada over C++.  Sadly, too
 many of these decisions are being made on the basis of what seems to
 be rather than what really is.

 Richard

 Richard Riehle
 richard@adaworks.com
 http://www.adaworks.com




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

* Re: Ada OO Mechanism
  1999-05-26  0:00                             ` Ray Blaak
@ 1999-05-26  0:00                               ` Hyman Rosen
  1999-05-26  0:00                               ` Richard D Riehle
  1 sibling, 0 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-26  0:00 UTC (permalink / raw)


Ray Blaak <blaak@infomatch.com> writes:
> Well, here is an OO example showing difficulties with the C++ model
> as compared to Ada.
> 
> Ada:
> 
> generic
>    type ScalarType is (<>); -- Is this right? My Ada is rusty.
> package Vector is
>    type T is private;
> 
>    function Create(size : Natural) : T;
> 
>    function "*" (vector : in T; scalar : in ScalarType) : T;
>    function "*" (scalar : in ScalarType; vector : in T) : T;
> private
>    -- whatever
> end;
> 
> declare
>    package IntVector is new Vector(Integer); 
>    use type IntVector;
>    package FloatVector is new Vector (Float); 
>    use type FloatVector;
> 
>    I : IntVector.T := IntVector.Create(3);
>    F : FloatVector.T := FloatVector.Create(3);
> begin
>    I := I*2;
>    I := 2*I;
>    F := F*2;
>    F := 2*F;
> end;

OK, here's the C++, which compiles without error with EGCS:

template <typename ScalarType>
struct Vector
{
	explicit Vector(int n);
	Vector operator *(ScalarType scalar) const;
	friend Vector operator *(ScalarType scalar, const Vector &v)
	{
		return v * scalar;
	}
};

int main()
{
	Vector<float> f(3);
	Vector<int> i(2);

	f * 2;
	2 * f;

	i * 7;
	7 * i;
}

> In this example, things won't link because I "forgot" to declare the
> Vector<float> friend function.

By writing the function inside the class, I've wriiten it once for
all types with which Vector is instantiated.

> The point is the C++ is a little more clumsy in this regard. If anyone has a
> way to do the C++ example cleanly, I would be most interested

And that was pretty much my point. People who know one language better
than another will often think that the other language is incapable or
clumsy at certain things. Often, this is not the case.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00       ` Hyman Rosen
  1999-05-25  0:00         ` David Starner
  1999-05-26  0:00         ` Ole-Hjalmar Kristensen
@ 1999-05-26  0:00         ` Laurent Guerby
  1999-05-26  0:00           ` Hyman Rosen
  2 siblings, 1 reply; 116+ messages in thread
From: Laurent Guerby @ 1999-05-26  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> as
> I believe this Ada --
> 
>    generic
> 	type S is abstract tagged private;
>    package P is
> 	type T is abstract new S with private;
> 	-- operations on T
>    private
> 	type T is abstract new S with
> 	   record
> 	      -- additional components
> 	   end record;
>    end P;
> 
> corrsponds to this C++ --
> [...]

As for your quest of finding an example of an OO construct
significantly easier in Ada than in C++, I don't think you'll find
something were the difference in implementation is that great, the OO
models are basically the same (but for multiple inheritance of
course).

I don't know if in C++ you can constrain a template type argument to
be of a specific class (type and class in the Ada sense). Here is a
slight variation of the Ada code you posted that uses this feature:

package P is
   type T is tagged null record;
   -- T ops
end P;

with P;
generic
   type GT is new P.T with private;
   --  This generic can be instanciated with any type in T'Class
package G is
   -- I can call T ops on GT objects.
   type GGT is new GT with null record;
   -- GGT has T ops too.
end G;

The Ada OO model guarantees that no dispatch operation will run
non-existing code (even in case of wild generics), I don't know if
it's true of the C++ one. Okay, it doesn't make any OO construct
easier, but you feel safer when this property is true ;-).

Not directly linked to OO constructs (I agree in advance ;-):

* In Ada, with discriminants you can easily have objects of varying
size being stack allocated instead of heap allocated. On the notation
size, I believe the Ada and C++ (vector<>) ways are equivalent but when
you put parallelism in the loop it doesn't look quite the same, heap
is global data so you have to lock when you use it, which can be
troublesome in some cases performance-wise.

* I don't know if self referencial types have a C++ equivalent (see
the Ada rationale for an example of such beast).

* You can "statically" create complex objects and elaboration issues
are correctly handled by the Ada definition, I don't think it's the
case in C++ (I think you don't know in what order the constructors
will be called for "static" data in C++, I might be wrong).

* What happens if a constructor or a destructor (C++ terminology)
raises an exception is fully specified in Ada, in particular in case
of a destructor exception, for each object in the scope its destructor
is given a chance to run, when this is done a big general ooops
exception is raised. I don't know if it is the case in C++.  This
applies too to function returning objects called as argument of
another subprogam.

--LG




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

* Re: Ada OO Mechanism
  1999-05-26  0:00         ` Laurent Guerby
@ 1999-05-26  0:00           ` Hyman Rosen
  1999-05-28  0:00             ` Laurent Guerby
  0 siblings, 1 reply; 116+ messages in thread
From: Hyman Rosen @ 1999-05-26  0:00 UTC (permalink / raw)


Laurent Guerby <guerby@acm.org> writes:
> I don't know if in C++ you can constrain a template type argument to
> be of a specific class (type and class in the Ada sense).

No, you can not. There are tricks that can accomplish the test, but
they are tricks, not basic language features. The C++ approach to
generics is "if it compiles, it works". Instead of restricting
a parameter to be of a certain type, you just write the template as
if the parameter has that type. It may be that a different type will
support the operations equally well, in which case there is no
reason to prevent the template from working. I understand that this
is unpleasant for many people who want to be able to say and see exactly
what's going on with the code.

> The Ada OO model guarantees that no dispatch operation will run
> non-existing code (even in case of wild generics), I don't know if
> it's true of the C++ one.

Yes, it's true. There will be either a compile-time or link-time
error if non-exisiting code is referenced. In no case will the
error be delayed to run-time.

> * In Ada, with discriminants you can easily have objects of varying
> size being stack allocated instead of heap allocated.

In C++ as well. In C++, you use a template parameter -

template <typename T, int N> struct Array { T a[N]; }
Array<int,5> ai;
Array<double,10> ad;

Ada is somewhat ahead here, though, because (if I'm not mistaken)
in Ada all the discrminated forms are the same type while in C++
they're not (i.e., in C++, Array<int,5> and Array<int,6> are
completely unrelated).

> * I don't know if self referencial types have a C++ equivalent (see
> the Ada rationale for an example of such beast).

struct SelfRef
{
	SelfRef &Me;
	SelfRef() : Me(*this) { }
};

> * You can "statically" create complex objects and elaboration issues
> are correctly handled by the Ada definition, I don't think it's the
> case in C++ (I think you don't know in what order the constructors
> will be called for "static" data in C++, I might be wrong).

For objects at file scope in a single compilation unit (a file),
constructors are called in top-to-bottom order. For static objects
within a function, constructors are called the first time the flow
of control passes through the definition. Order of initialization
across compilation units is unspecified.

> * What happens if a constructor or a destructor (C++ terminology)
> raises an exception is fully specified in Ada, in particular in case
> of a destructor exception, for each object in the scope its destructor
> is given a chance to run, when this is done a big general ooops
> exception is raised. I don't know if it is the case in C++.  This
> applies too to function returning objects called as argument of
> another subprogam.

It's fully specified in C++ as well. When a constructor throws, any
already constructed sub-components are destructed. As scopes are left
in search of an exception handler, all constructed objects in those
scopes are properly destructed. If during this process a destructor
throws an exception unhandled within itself, a special termination
handler is called. C++ cognoscenti have concluded that you should not
throw exceptions from destructors because of this.




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

* Re: Ada OO Mechanism
  1999-05-26  0:00                               ` Richard D Riehle
@ 1999-05-26  0:00                                 ` Hyman Rosen
  1999-05-27  0:00                                   ` Richard D Riehle
                                                     ` (2 more replies)
  0 siblings, 3 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-26  0:00 UTC (permalink / raw)


Richard D Riehle <laoXhai@ix.netcom.com> writes:
> For example, in the same scope and visibility
>          type T is tagged ...
>          function Get(F : some-file) return T;
>          function Get(F : access some-file) return T;
>          function Get(F : some-file) return T'Class;
>          type B is new T with ...
>          function Get(F : some-file) return B;
>          function Get(F : access some-file) return B;

Overloading by return type and having that control dispatching looks
like a good example of something that you can't do in C++. So is the
concept of class-wide type itself - there's no equivalent in C++ for
Ada's T'Class type. From a little fooling around with your code above
and gnat, and the Rationale, it looks like the compiler has to examine
the code that attempts to initialize a T'Class variable and allocate
the maximum space for it that that code would require. C++ doesn't do
any of that - C++ coders would be using dynamic allocation and pointers
or references to pass around arbitray subclasses. Interesting.

>  One of the original contentions was that, although the C++ model of
>              class <=> type <=> module
>  appears to be simpler on the surface, as one begins to design large
>  scale software, that model becomes something of a straightjacket. It
>  utltimately requires friend functions and other encapsulation-breaking
>  features (such as the new "mutable" reserved word) to get around the
>  restrictions imposed by such a small model of object-oriented 
>  programming.

It is a fallacy that friend functions break encapsulation. Friendship
is granted explicitly by a class. These friends are part of the
encapsulation. Mutable has nothing at all to do with this - mutable
members of an object may be modified even when the object is declared
to be 'const'. The intent is to provide a difference between logical
constness and physical constness. For example, one would expect that
the characters of a const string would never change, but there could
be an internal reference count that needs adjustment. That count would
be declared mutable.

For completeness sake, class member templates *can* be used to break
encapsulation. The C++ philosophy is to protect encapsulation against
Murphy but not Machiavelli.




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

* Re: Ada OO Mechanism
  1999-05-26  0:00                                 ` Hyman Rosen
@ 1999-05-27  0:00                                   ` Richard D Riehle
  1999-06-05  0:00                                     ` Matthew Heaney
  1999-05-28  0:00                                   ` Laurent Guerby
  1999-06-05  0:00                                   ` Matthew Heaney
  2 siblings, 1 reply; 116+ messages in thread
From: Richard D Riehle @ 1999-05-27  0:00 UTC (permalink / raw)


In article <t7k8tvqyjr.fsf@calumny.jyacc.com>,
	Hyman Rosen <hymie@prolifics.com> wrote:

>Richard D Riehle <laoXhai@ix.netcom.com> writes:
>> For example, in the same scope and visibility
>>          type T is tagged ...
>>          function Get(F : some-file) return T;
>>          function Get(F : access some-file) return T;
>>          function Get(F : some-file) return T'Class;
>>          type B is new T with ...
>>          function Get(F : some-file) return B;
>>          function Get(F : access some-file) return B;
>
>Overloading by return type and having that control dispatching looks
>like a good example of something that you can't do in C++. So is the
>concept of class-wide type itself - there's no equivalent in C++ for
>Ada's T'Class type. From a little fooling around with your code above
>and gnat, and the Rationale, it looks like the compiler has to examine
>the code that attempts to initialize a T'Class variable and allocate
>the maximum space for it that that code would require. C++ doesn't do
>any of that - C++ coders would be using dynamic allocation and pointers
>or references to pass around arbitray subclasses. Interesting.

 In actual Ada OOP, especially when using Stream_IO for storage
 of heterogenuous types, it is typical to use access (pointer) types
 also.  One reason I used the illustration with access parameters
 is to accomodate that practice.

 Now for the bad news.  Ada access parameters allow the programmer
 to violate the encapsulation too.  Although the access parameter
 itself is regarded as an in parameter in Ada, a programmer may
 dereference data being referenced, if there is visibility to the
 data.  In this regard, I think C++ is a little stronger because of
 the option of const functions and const parameters.  My preference
 for a future addition to the Ada standard would be some kind of
 constant function such as,

    constant function F (A : access some-type) return T;

 or, closer to C++,

    function F (A : constant access some-time) return T;

 which would disallow any monkey business with the function. In fact,
 this would correspond to the notion of a query with no possible ]
 side-effects (much like the protected type function) and satisfy
 Bertrand Meyer's insistence that queries should only query and 
 modifiers should only modify.  

 This is one feature of Ada, for object-oriented programming where
 I think C++ is a little stronger.  

>It is a fallacy that friend functions break encapsulation. Friendship
>is granted explicitly by a class. These friends are part of the
>encapsulation. 

 Friends are "part of the encapsulation", but also seem, to me, to be
 an awkward feature included to compensate for problems associated
 with the   class <=> type <=> module   model.   Without this kind
 of model, the notion of friends would be unnecessary.     

>Mutable has nothing at all to do with this - mutable
>members of an object may be modified even when the object is declared
>to be 'const'. The intent is to provide a difference between logical
>constness and physical constness. For example, one would expect that
>the characters of a const string would never change, but there could
>be an internal reference count that needs adjustment. That count would
>be declared mutable.

 I understand that mutable is a feature for reversing const'ness. We
 have in Ada the notion of a general access constant that satisfies
 the situation you mention, if I understand your explanation.  It just
 seems, once again, that this is an add-on to compensate for a language
 weakness rather than a coherent part of the overall design.  
 
>For completeness sake, class member templates *can* be used to break
>encapsulation. The C++ philosophy is to protect encapsulation against
>Murphy but not Machiavelli.

 This is a key difference between Ada and C++.  Ada, the language,
 is designed to maximize the number of errors that can be caught
 during compilation, as early in the process as possible.  This is
 one reason for requiring that ancestral library units be correctly
 compiled before one can compile a dependent unit.  It is one reason
 why access types (pointers) are so strictly controlled, and it is
 also why we have, in Ada, a strong separation between the notions of
 scope and visibility.  

 The philosophies of the two language designs are different.  As you
 noted earlier regarding templates, if it compiles in C++, it is OK,
 but there may be problems lurking in the code.  In Ada, the goal is
 to ensure that a compiled template (generic) correspond completely to
 the associated signatures of generic formal parameters.  This is one
 reason Ada generic formal package parameters seem, at first, to be
 more bizzare than those in C++.  We are trying to put both Murphy and
 Machiavelli out of business.  Too ambitious.  Probably.  But that is
 the goal, and one reason why Ada is designed as it is.  

 I have enjoyed our little discussions.  Thanks for your participation.
 It is now essential I return to doing some real programming even though
 this has been fun.

 Thanks, Hyman,

 Richard Riehle
 richard@adaworks.com
 http://www.adaworks.com
 




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                           ` Chris
  1999-05-25  0:00                             ` David Botton
@ 1999-05-27  0:00                             ` Samuel Mize
  1 sibling, 0 replies; 116+ messages in thread
From: Samuel Mize @ 1999-05-27  0:00 UTC (permalink / raw)


Chris <Chris@newsguy.com> wrote:
> In article <7if7oj$bee@news1.newsguy.com>, Samuel says...
>>
>>I do know that this distinction is extremely useful in a mixed-method
>>environment, e.g., object-oriented and procedural elements working
>>together.
>>
> 
> I don't think it leads to clear design when one part of the
> program is done in OO ways, while another part is not.
> 
> one either uses all OO, or all procedural.
> 
> don't you agree?

Nope.

But then I've worked on very large systems, with multiple fairly
independent subsystems interacting inside the language.  For
instance, we had an object-oriented design which needed object
persistence -- that is, many objects stored their attributes
between executions of the system, re-reading their current state
at start-up.  The repository for these objects was really just a
simple data base in this design, and when we tried to switch it to
an object-oriented implementation it was much less clear, less
maintainable, and slower.

Another example would be a process control system that interacts with
things like inventory control and materials routing.  I could easily
imagine that you would want to implement safety-critical control
loops in a very controlled procedural fashion -- in this area, you
are inherently thinking about actions more than objects anyway.
Then you could interface this to an object-oriented representation
of the physical objects being manipulated.

In short, I've worked in mixed-method environments, and as long as
you clearly define where each method is going to be used, it's quite
useful and powerful.

At SOME point you stop doing OO work and switch to a procedural
model, at least when implementing a class's method bodies.  Unless,
of course, you're coding in something like Smalltalk that is
object-oriented all the way down to integers (I understand).  I
don't think you'll sell the argument that this is necessary, or
even clearer to most people than procedurally-coded methods.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                     ` Richard D Riehle
  1999-05-25  0:00                       ` David Botton
@ 1999-05-27  0:00                       ` Aidan Skinner
  1 sibling, 0 replies; 116+ messages in thread
From: Aidan Skinner @ 1999-05-27  0:00 UTC (permalink / raw)


On Tue, 25 May 1999 20:04:20 GMT, Richard D Riehle
<laoXhai@ix.netcom.com> wrote: 

> on his pipe organ.  On the other hand, Tocatta and Fuge in D Minor
> is a bit of a stretch for my banjo and Foggy Mountain Breakdown
> sounds a little strange on the pipe organ.  

Ah, but have you heard my post-modern neoclassical avant garde
desconstructionist version of "Smoke On The Water" on trash can and
hose pipe?

;)

- Aidan
-- 
http://www.skinner.demon.co.uk/aidan/
Real men whistle ed commands at 300 baud into a can.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                             ` David Botton
@ 1999-05-27  0:00                               ` Aidan Skinner
  1999-05-27  0:00                                 ` Gautier
  0 siblings, 1 reply; 116+ messages in thread
From: Aidan Skinner @ 1999-05-27  0:00 UTC (permalink / raw)


On Tue, 25 May 1999 22:25:38 -0400, David Botton <David@Botton.com> wrote:

>If Perl is the duct tape of programming languages, Ada is the Rambo
>knife of engineering. (OK maybe swiss army fit better ...)

Personally leatherman is my knife of choice... you can do all you can
do with a swiss army knife, but it's better constructed and has a
couple of nifty features I've not seen on a swiss army knife (like
pliers, wire cutters/strippters etc.).

;)

- Aidan (knife flame war anybody?)
-- 
http://www.skinner.demon.co.uk/aidan/
Real men whistle ed commands at 300 baud into a can.




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

* Re: Ada OO Mechanism
  1999-05-27  0:00                               ` Aidan Skinner
@ 1999-05-27  0:00                                 ` Gautier
  0 siblings, 0 replies; 116+ messages in thread
From: Gautier @ 1999-05-27  0:00 UTC (permalink / raw)


> Personally leatherman is my knife of choice... you can do all you can
> do with a swiss army knife, but it's better constructed and has a
> couple of nifty features I've not seen on a swiss army knife (like
> pliers, wire cutters/strippters etc.).
> 
> ;)
> 
> - Aidan (knife flame war anybody?)

OK!

Pliers are not in the predefined library of a swiss knife, of course.
_But_ as for cutting or stripping wires, I claim that the main blade is
a nice generic tool for it!

-- 
Gautier

--------
http://members.xoom.com/gdemont/




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                       ` Hyman Rosen
                                           ` (2 preceding siblings ...)
  1999-05-25  0:00                         ` Richard D Riehle
@ 1999-05-27  0:00                         ` Samuel Mize
  1999-05-27  0:00                           ` Hyman Rosen
  1999-05-27  0:00                         ` Samuel Mize
  4 siblings, 1 reply; 116+ messages in thread
From: Samuel Mize @ 1999-05-27  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> wrote:
> Samuel Mize <smize@imagin.net> writes:
>>   -- This dispatches on both parameters, so they have to match
>>   -- at run-time
>>   procedure Operation_4 (A: A_Type; B: B_Type);
> 
> (Do you mean B: A_Type ?)
> 
> Thanks, this is the kind of example I meant! This is something that
> C++ can't do by itself. When you say "match at runtime" do you mean
> that their dynamic types must be the same? Does the code raise an
> exception if they happen not to match?

Yep.

I said elsewhere I'd bone up on this and explain it.  Here goes.  I
haven't been actually using this for a couple of years (dang it), so
everybody else backstop me and catch any errors.

In a call on a potentially dispatching function or procedure, all the
tags of the controlling parameter values have to match, or you get a
constraint error at run-time.  And, they must be all statically tagged
or all dynamically tagged.

A value can be statically tagged, dynamically tagged, or tag
indeterminate.

- It's statically tagged if it is of a specific tagged type.

- It's dynamically tagged if it's of a class-wide type.

- It's tag indeterminate ONLY if it's a function call, AND its
  parameters (if any) don't determine its tag.  (Such a function call
  must be able to determine the tag to use for its result from the
  context of the call.)

Note that the tag of a function call depends on the tags of its
parameters.  It's statically or dynamically tagged, whichever the
parameters are.  If there are no statically or dynamically tagged
parameters, the call is tag indeterminate, and you have to be able to
tell from the context of the call what tag to use.

Here is a little example code.  Given the package:

    package T_Types is
      type T1 is tagged null record;

      procedure Op1 (P1: T1; P2: T1);

      type T1_Class_Access is access T1'Class;

      type T1_1 is new T1 with null record;
      -- implicit op1 declared here

      type T2 is tagged null record;

      procedure Op1 (P1: T1'class; P2: T2);

    end t_types;

And the following data items:

    V1: T1;
    V1_1: T1_1;
    V1_Class_Access: T1_Class_Access := new T1;

    V2: T2;

Then we can have the following calls, some of which are illegal
at compile time and one of which raises Constraint_Error at
run time:

    ---------
    -- DISPATCHING TO SUBTYPES OF T1
    ---------

    -- legal -- static call to T1.op1
    op1 (V1, V1);

    -- not legal, tags must match
    --op1 (V1, V1_1);

    -- not legal, must both be either static or dynamic tagged
    --op1 (V1, V1_Class_Access.all);

    -- legal -- dispatching call to op1 in some descendant of T1
    op1 (V1_Class_Access.all, V1_Class_Access.all);

    -- legal -- both are now dynamically tagged
    op1 (T1'Class (V1), V1_Class_Access.all);

    -- legal at compile time, but fails at run time because the
    -- tags don't match
    --op1 (T1'Class (V1_1), V1_Class_Access.all);

    ---------
    -- DISPATCHING TO SUBTYPES OF T2
    ---------

    -- all legal
    op1 (V1, V2);
    op1 (V1_1, V2);
    op1 (V1_Class_Access.all, V2);

I hope you find this of some interest.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                       ` Hyman Rosen
                                           ` (3 preceding siblings ...)
  1999-05-27  0:00                         ` Samuel Mize
@ 1999-05-27  0:00                         ` Samuel Mize
  1999-05-27  0:00                           ` Jon S Anthony
  4 siblings, 1 reply; 116+ messages in thread
From: Samuel Mize @ 1999-05-27  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> wrote:
>... object-oriented techniques
> that were harder, or less elegant, in C++ than in Ada. I asked
> for examples with the thought that perhaps the posters didn't know
> C++ as well as they knew Ada,

As an aside, with the background that I happen to have, I can more
easily multiply examples of object-oriented methods that are not
supported in either language.  Since I know that C++ implements a
specific method, and that Ada's facilities are more generally
oriented, it has been easy for me to believe the assertions of others
that they find the C++ model restrictive in some instances.

Logic programming is a simple example.

In at least one Actor-based method that I am aware of, a message is
itself an object, and can, while it exists, send and recieve messages.
This certainly doesn't fit in with the model of a "message" being a
function (or procedure) call, which is basic to the object-oriented
programming model of both C++ and Ada.

Again, there are some AI-type object-oriented systems that generate
new subclasses on the fly, altering their fields and giving them new
methods.  These are generally written in Lisp, where one can execute
data.  To do this in either C++ or Ada, one would have to write
roughly the equivalent of a Lisp interpreter in the base language,
and then really write most of the program in that new language.

By the way, one other point about Ada's "object-oriented" syntax is
that it supports non-object-oriented programming by extension.  This
allows one to write base code, then write new code that extends the
functionality of the old code without recompiling the base code.  You
can do this in C++ with classes, but you don't have to design in a
class-based model to do this in Ada.  If you're interested, I
discussed this in appalling detail earlier -- do a Deja News power
search on the phrase "infinite case statement" in comp.lang.ada, and
read my "shorter and new" posting on the subject.  (It took me a
couple of tries to explain it clearly.)

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-27  0:00                         ` Samuel Mize
@ 1999-05-27  0:00                           ` Jon S Anthony
  0 siblings, 0 replies; 116+ messages in thread
From: Jon S Anthony @ 1999-05-27  0:00 UTC (permalink / raw)


> 
> Hyman Rosen <hymie@prolifics.com> wrote:
> >... object-oriented techniques
...
> Again, there are some AI-type object-oriented systems that generate
> new subclasses on the fly, altering their fields and giving them new
> methods.

Right.  This sort of thing is easy in CLOS.  What's more, if you use
the MOP you can even change how dispatching behaves, etc.  Of course,
you also have true multiple dispatch as well.


> These are generally written in Lisp, where one can execute
> data.  To do this in either C++ or Ada, one would have to write
> roughly the equivalent of a Lisp interpreter in the base language,
> and then really write most of the program in that new language.

Right.  Which is why we switched to Lisp (after trying both Ada and
C++ <with Ada by far the better of those two>).  What's more, since
moder CommonLisp implementations come with optimizing _compilers_
built in and dynamically accessible, you'd have to write (or hook to)
optimizing code generators as well.  Otherwise, you'd be sucking wind
in performance.  You'd also have to write/aquire a GC and optimize it.
Of course, if you go to this effort, you may as well bag the original
application and become a Lisp vendor.


> Sam Mize

/Jon

-- 
Jon Anthony
Synquiry Technologies, Ltd. Belmont, MA 02478, 617.484.3383
"Nightmares - Ha!  The way my life's been going lately,
 Who'd notice?"  -- Londo Mollari




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

* Re: Ada OO Mechanism
  1999-05-27  0:00                         ` Samuel Mize
@ 1999-05-27  0:00                           ` Hyman Rosen
  1999-05-28  0:00                             ` Samuel Mize
  1999-05-28  0:00                             ` Laurent Guerby
  0 siblings, 2 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-05-27  0:00 UTC (permalink / raw)


Samuel Mize <smize@imagin.net> writes:
> I hope you find this of some interest.

I'm trying to wrap my head around this class-wide type stuff.
I'm still at that stage of pre-clarity confusion :-)

Here's some code I threw at gnat, based on Richard D. Riehle's example.

-- in ft.ads
package ft is
	m: boolean;
	type S is null record;
	a_f: S;
	type T is abstract tagged null record;
	function Get(F: S) return T is abstract;
	function GetC(F: S) return T'Class;
	type A is new T with null record;
	function Get(F: S) return A;
	a_a: A;
	type B is new T with null record;
	function Get(F: S) return B;
	a_b: B;
end;

-- in ft.adb
package body ft is
	function GetC(F: S) return T'Class is
	begin if m then return a_a; else return a_b; end if; end;
	z: T'Class := GetC(a_f);
	function Get(F: S) return A is begin return a_a; end;
	function Get(F: S) return B is begin return a_b; end;
begin
	z := Get(a_f);
end;

Gnat complains about the assignment to z:
ft.adb:8:14: ambiguous expression (cannot resolve "Get")
ft.adb:8:14: possible interpretation at ft.ads:12
ft.adb:8:14: possible interpretation at ft.ads:9
ft.adb:8:14: possible interpretation at ft.ads:6

From reading the Rationale, I thought that the assignment to z would
result in a dispatching call to Get, using the tag of z that was set
at its initialization. What am I doing wrong here? How do controlling
return types work?




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

* Re: Ada OO Mechanism
  1999-05-27  0:00                           ` Hyman Rosen
@ 1999-05-28  0:00                             ` Samuel Mize
  1999-05-28  0:00                             ` Laurent Guerby
  1 sibling, 0 replies; 116+ messages in thread
From: Samuel Mize @ 1999-05-28  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> wrote:
> Samuel Mize <smize@imagin.net> writes:
>> I hope you find this of some interest.
> 
> I'm trying to wrap my head around this class-wide type stuff.
> I'm still at that stage of pre-clarity confusion :-)
> 
> Here's some code I threw at gnat, based on Richard D. Riehle's example.
...
> Gnat complains about the assignment to z:
> ft.adb:8:14: ambiguous expression (cannot resolve "Get")
> ft.adb:8:14: possible interpretation at ft.ads:12
> ft.adb:8:14: possible interpretation at ft.ads:9
> ft.adb:8:14: possible interpretation at ft.ads:6

I did a direct cut and paste to files on my system here and it
worked fine.  One of us must have an old version of GNAT.  I'm
using GNAT 3.10 on Windows.

I can see an argument that, since a tag-indeterminate value is
going into a class-wide type variable, the tag is not determined:

> 	z: T'Class := GetC(a_f);
...
> begin
> 	z := Get(a_f);

But, like you, I believe the code is correct.  You can't have an
uninitialized (tag undetermined) class-wide variable, so it ought
to dispatch on that tag.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-05-28  0:00                               ` Richard D Riehle
@ 1999-05-28  0:00                                 ` Tom Moran
  0 siblings, 0 replies; 116+ messages in thread
From: Tom Moran @ 1999-05-28  0:00 UTC (permalink / raw)


> M : Machine'Class := Get(container-name);
We use that in Claw. For instance
DIB : Claw.Bitmaps.Root_DIBitmap_Type'Class
   := Claw.Bitmaps.IO.Read("xxx.bmp");
so DIB can be a VGA_DIBitmap_Type or a Mono_DIBitmap_Type or whatever.
Then writing, or putting it on the clipboard, or whatever, dispatches
on the particular kind.




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                   ` Hyman Rosen
  1999-05-25  0:00                     ` Richard D Riehle
  1999-05-25  0:00                     ` Samuel Mize
@ 1999-05-28  0:00                     ` Robert I. Eachus
  1999-05-28  0:00                       ` Brian Rogoff
  1999-05-29  0:00                       ` Ehud Lamm
  1999-06-03  0:00                     ` Matthew Heaney
  3 siblings, 2 replies; 116+ messages in thread
From: Robert I. Eachus @ 1999-05-28  0:00 UTC (permalink / raw)
  To: Hyman Rosen



Hyman Rosen wrote:
 
> > 2) It therefore CANNOT be made virtual so you can't dispatch on it.
> 
> So you mean in Ada, I can write a dot(a,b) which will dispatch on
> either a or b? I wasn't aware that this was the case.

    Technically you can't, but in practice you can.  Ada allows both
classwide and dispatching parameters.  Multiple dispatching is done by
having a visible operation which is classwide for one or more
parameters, then sorting out the cases and dispatching on the second
parameter.  Huh?  Maybe this does take an example.  Let's say that we
need a matrix package that allows multiple representations of matrices. 
Some specialized to save storage such as identity matrices, tridiagonal
matrices, etc. and some representations which simplify further
operations while representing arbtrary matrices:  scaled matrices, LUP
decomposition, basis representation, etc.   In Ada, I create a package
which provides the basic operations of the type:

with Ada.Finalization;
package Matrices is

   type Matrix(X,Y: Integer := 0) is abstract tagged private;
   -- X and Y provide the bounds, the defualt value is to allow
different       -- sized values to be assigned to objects.
 
   function Create_Zero_Matrix (X,Y: Integer) return Matrix;
   procedure Set_Element(M: in out Matrix; X,Y: in Integer; To: Float);
 
   function "*" (L,R: Matrix'Class) return Matrix'Class;
   function "+" (L,R: Matrix'Class) return Matrix'Class;
   function "-" (L,R: Matrix'Class) return Matrix'Class;
   -- etc...

private
   ...
   type Matrix(X,Y: Integer := 0) is new Ada.Finalization.Controlled
            with null record;
   -- No data in abstract base type.
   function Multiply1(L: Matrix; R: Matrix'Class) return Matrix'Class;
   function Multiply2(L,R: Matrix) return Matrix'Class;
   function To_Standard_Rep(From: Matrix) return Matrix'Class;
   -- etc...
end Matrices;

-- Now we need some Child packages that declare the various actual --
representation.  Let's start with the unrestricted standard --
representation.

package Matrices.Standard is

   type Standard_Matrix is new Matrices.Matrix with private;

private
 
   procedure Adjust(Object: in out Standard_Matrix);
   procedure Finalize(Object: in out Standard_Matrix);
   -- overrides for the Controlled operations. 
   type Data_Array is array (Integer range <>, Integer range <>) of
Float;
   type Data_Pointer is access all Data;
   type Standard_Matrix is new Matrices.Matrix with record
     Data: Data_Pointer := new Data_Array'(1..X =>(1..Y => 0.0));
   end record;
   function Multiply1(L: Standard_Matrix; R: Matrix'Class)
        return Matrix'Class;
   function Multiply2(L,R: Standard_Matrix)
        return Matrix'Class;
   function ToStandard_Rep(From: Matrix) return Matrix'Class;
  
end Matrices.Standard;

-- Let's have at least two children...

package Matrices.Identity is

   type Identity_Matrix is new Matrices.Matrix with private;

   function Create_Identity_Matrix (Size: Integer) return
Identity_Matrix;

   function Create_Zero_Matrix (Size: Integer) return Identity_Matrix;

private
 
   procedure Initialize(Object: in out Identity_Matrix);
   -- Since there is no data we don't need a Adjust and Finalize,
   -- but I want to check that X = Y in Initialize.
 
   type Identity_Matrix is new Matrices.Matrix with null record;

   function Multiply1(L: Identity_Matrix; R: Matrix'Class)
        return Matrix'Class;
   function Multiply2(L,R: Identity_Matrix)
        return Matrix'Class;
   function To_Standard_Rep(From: Identity_Matrix) return Matrix'Class;
   ...

end Matrices.Identity;

-- might as well do the body for this one...

with Matrices.Standard;
package body Matrices.Identity is

    function Create_Identity_Matrix return Identity_Matrix is
       Result: Identity_Matrix(X,Y);
    begin return Result; end Create_Identity_Matrix;

    function Initialize(Object: in out Identity_Matrix) is
    begin if X /= Y then raise Constraint_Error; end Initialize;

     function Multipy1(L: Identity_Matrix; R: Matrix'Class)
          return Matrix'Class is
     begin return R; end Multiply1;

     function Multiply2(L,R: Identity_Matrix) return Matrix'Class is
     begin return R; end Multiply2;

     function To_Standard_Rep(From: Identity_Matrix) return Matrix'Class
is
        Result: Matrices.Standard.Standard_Matrix(From.X,From.Y);
     begin
        -- counts on the Standard_Matrix being intialized to all zeros.
        for I in 1..From.X loop
          Result.Data(I,I) := 1.0;
        end loop;
        return Result;
     end To_Standard_Rep;

end Matrices.Identity;

-- okay now part of the parent package body.

package body Matrices is

     ...
     function "*"(L,R: Matrix'Class) return Matrix'Class is
     begin
       if L.Y /= R.X raise Constraint_Error; end if;
       -- might as well do this in the classwide operation, since it is
       -- independent of representation.
       if L'Tag = R'Tag then return Multiply2(L,R);
       else return Multiply1(L,R);
       end if;
     end "*";
     ...

end Matrices;

    If this were a real implementation, I would probably make some of
the operations in Matrices explicitly abstract, and have more classwide
conversion functions such as to an LUP decomposition.  And of course, in
a real implementation the body of "*" would be much more complex,
preferring to call the Identity_Matrix operation even when the identity
matrix or tridiagonal matrix is the right parameter as well, etc.  But
the genenral idiom requires a minimum of one private dispatching
operation for each public classwide operation, which is very little
overhead compared to single dispatching.

    Also note that this is really double dispatching, but if you wanted
to declare "*" as:

    function "*"(L,R: Matrix'Class) return Matrix;

    The you would be doing triple dispatching, with the first dispatch
on the return type, without much more implementation effort.  Such a
package might be useful if most of your matrices were in either LUP or
basis form.

>                                                        I actually
> think that this is in fact *not* the case, in which case I have no
> trouble writing a dispatching version in C++ either - just have
> dot(a,b) call a.dot(b). In both Ada and C++, the apparent external
> symmetry will then hide the internal asymmetry.

    As you point out it is not impossible to do that in C++ as well. 
But notice Multiply2, which dispatches on both L and R, or for that
matter "*" doesn't dispatch on anything externally, even though it
effectively double dispatches.  (The difference is that in Multiply2
both parameters must be of the same type (subclass), while in "*" they
need not be types that know of each other.  One of the cute things you
can do with a complex dispatching case, is put an error handler on "*"
like so:

     function "*"(L,R: Matrix'Class) return Matrix'Class is
     begin
       if L.Y /= R.X raise Constraint_Error; end if;
       -- might as well do this in the classwide operation, since it is
       -- independent of representation.
       begin
         if L'Tag = R'Tag then return Multiply2(L,R);
         elsif ...
         else return Multiply1(L,R);
         end if;
       exception
         when Constraint_Error =>
              return Multipy2(To_Standard_Rep(L),To_Standard_Rep(R));
       end;
     end "*";

     Of course more likely is to recognize the unanticipated cases in
the various Multiply1 functions with:

     else return Multiply1(L,To_Standard_Rep(R));

(You don't have to do this as a recursive call, but it works cleanly,
and doesn't take much code for these presumably rare or unanticipated
cases.) 
 
> Once again, I will ask for an example demonstrating this, where
> something is more complicated to use in C++ generics than in Ada.
> This will make you the fourth person I have asked for this type
> of example, the others being Richard D. Riehle, Samuel Mize, and
> Robert Dewar. None of the others have chosen to post such an
> example.

     I've done one example (probably with a few typos and thinkos since
it is Friday afternoon), I'm not going to do this one too.  The reason
no one is anxious to demonstrate this is that reasonable examples take
several pages of code in Ada, and of course lots more in C++.
-- 

                                        Robert I. Eachus

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




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

* Re: Ada OO Mechanism
  1999-05-28  0:00                     ` Robert I. Eachus
@ 1999-05-28  0:00                       ` Brian Rogoff
  1999-05-29  0:00                       ` Ehud Lamm
  1 sibling, 0 replies; 116+ messages in thread
From: Brian Rogoff @ 1999-05-28  0:00 UTC (permalink / raw)


On Fri, 28 May 1999, Robert I. Eachus wrote:
> Hyman Rosen wrote:
> > Once again, I will ask for an example demonstrating this, where
> > something is more complicated to use in C++ generics than in Ada.
> > This will make you the fourth person I have asked for this type
> > of example, the others being Richard D. Riehle, Samuel Mize, and
> > Robert Dewar. None of the others have chosen to post such an
> > example.
> 
>      I've done one example (probably with a few typos and thinkos since
> it is Friday afternoon), I'm not going to do this one too.  The reason
> no one is anxious to demonstrate this is that reasonable examples take
> several pages of code in Ada, and of course lots more in C++.

I think that there are a few examples of reasonably short length, going 
in each direction (Ada > C++ and C++ > Ada). I thought one of the original 
preconditions was OO, but if its just generics, then the example Richard 
O'Keefe presented a few years ago during one of the downward closure 
discussions where he used Ada generics to simulate downward closures is 
probably a good "pro-Ada" one, though I think the intent of the original 
example was to show how bad Ada came off against Pascal and Scheme. Note
that using generics this way doesn't even really do a good job compared 
to what you could do with downward closures; your Integrate_2D wouldn't 
have to be tied to a particular Integrate_1D, you could just pass it in as 
an argument. Any nice way around that problem, besides using GNAT specific 
features? Anyways, I don't think this translates easily to C++, but if 
Hyman or someone else can surprise me I'd be delighted.

-- First we write a simple 1-D integrator using the trapezoid rule

generic
    type Float_Type is digits;
    with function F(X : Float_Type) return Float_Type;
function Integrate_1D(Lower, Upper: Float_Type; Steps : Positive) 
		      return Float_Type;

-- Tail recursive trapezoid rule, a tip o' the hat to Schemers!

function Integrate_1D(L1, U1: Float_Type; Steps : Positive)
                      return Float_Type is
    Dx : constant Float_Type := (Upper - Lower) / Float_Type(Steps);
    function Iterate( Step : Positive; Value : Float_Type )
                     return Float_Type is
    begin
        if Step = Steps then
            return DX * Current_Value;
        else
            return Iterate( Step + 1,
                           Value + F(Lower + Float_Type(Step) * Dx));
        end if;
    end Iterate;
begin
    Iterate(1, .5 * F(Lower) + F(Upper));
end;

-- The 2-D integration spec

generic
    with function F(X, Y : Float_Type) return Float_Type;
function Integrate_2D(L1, U1, L2, U2: Float_Type; S1, S2 : Positive)
                      return Float_Type;

-- How I wish Ada 95 had real downward closures!!!

function Integrate_2D(L1, U1, L2, U2: Float_Type) return Float_Type is
    function Outer_Integrand(Y: Float_Type) return Float_Type is
        function Inner_Integrand(X: Float_Type) return Float_Type is
        begin
            return F(X, Y);
        end Inner_Integrand;

        function Inner_Integrator is
          new Integrate_1D(F => Inner_Integrand, Steps => S1);
    begin
        return Inner_Integrator(L1, U1);
    end Outer_Integrand;

    function Outer_Integrator is
      new Integrate_1D(F => Outer_Integrand, Steps => S2);
begin
    return Outer_Integrator(L2, U2);
end Integrate_2D;

-- Brian






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

* Re: Ada OO Mechanism
  1999-05-28  0:00                             ` Laurent Guerby
@ 1999-05-28  0:00                               ` Richard D Riehle
  1999-05-28  0:00                                 ` Tom Moran
  0 siblings, 1 reply; 116+ messages in thread
From: Richard D Riehle @ 1999-05-28  0:00 UTC (permalink / raw)


In article <86lne9qh28.fsf@ppp-159-70.villette.club-internet.fr>,
	Laurent Guerby <guerby@acm.org> wrote:

>Hyman Rosen <hymie@prolifics.com> writes:
>> [...]
>> From reading the Rationale, I thought that the assignment to z would
>> result in a dispatching call to Get, using the tag of z that was set
>> at its initialization. What am I doing wrong here? How do controlling
>> return types work?
>
>A variable, once given an initial value, never change its type in
>Ada. So the assignment to a class wide variable can only be done in a
>declarative part.
>
>--LG

Declarative parts can appear in subprograms or declare blocks. Therefore,
one can take advantage of the ability to declare classwide variables in
some interesting ways.  Given a tagged type,

          type Machine is tagged ...

with derviations,

          type Big_Machine is new Machine with ...
          type Solenoid is new Machine with ...
          type Tractor is new Big_Machine with ...

one could dynamically dispatch to some operation overridden for each kind 
of machine such as,

          procedure Turn_On(M : in out Machine);

If we also provide a classwide Get operation that retrieves objects
of type Machine'Class from some kind of container,

          function Get (C : in Container) return Machine'Class;

then we can have a loop that looks like this,

         loop
            declare
               M : Machine'Class := Get(container-name);
                  -- constrains M with classwide Get function
            begin
               Turn_On(M);
            end;
         end loop;

where the classwide variable will be constrained by the Get operation
each time through the loop.  This technique can be used in subprograms,
tasks, or declare blocks.  I have an example I use in some of my classes
that demonstrates several variations on this for Stream_IO files. For
Stream_IO you would want to use Machine'Class'Input(filename). It
works quite nicely and is simple to implement and understand.

Richard Riehle
richard@adaworks.com
http://www.adaworks.com




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

* Re: Ada OO Mechanism
  1999-05-26  0:00                                 ` Hyman Rosen
  1999-05-27  0:00                                   ` Richard D Riehle
@ 1999-05-28  0:00                                   ` Laurent Guerby
  1999-06-05  0:00                                   ` Matthew Heaney
  2 siblings, 0 replies; 116+ messages in thread
From: Laurent Guerby @ 1999-05-28  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:
> [...]
> From a little fooling around with your code above
> and gnat, and the Rationale, it looks like the compiler has to examine
> the code that attempts to initialize a T'Class variable and allocate
> the maximum space for it that that code would require. C++ doesn't do
> any of that - C++ coders would be using dynamic allocation and pointers
> or references to pass around arbitray subclasses. Interesting. [...]

I think most Ada implementation use a secondary stack where such
dynamix sized beasts are built, there's no need for "maximum space"
allocation. Note that this feature of Ada is not linked to OO, the
same mechanism is in place for function returning dynamically sized
arrays. Of course the cost of this is spurious copying if the compiler
isn't very clever.

--LG




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

* Re: Ada OO Mechanism
  1999-05-27  0:00                           ` Hyman Rosen
  1999-05-28  0:00                             ` Samuel Mize
@ 1999-05-28  0:00                             ` Laurent Guerby
  1999-05-28  0:00                               ` Richard D Riehle
  1 sibling, 1 reply; 116+ messages in thread
From: Laurent Guerby @ 1999-05-28  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:
> [...]
> From reading the Rationale, I thought that the assignment to z would
> result in a dispatching call to Get, using the tag of z that was set
> at its initialization. What am I doing wrong here? How do controlling
> return types work?

A variable, once given an initial value, never change its type in
Ada. So the assignment to a class wide variable can only be done in a
declarative part.

--LG




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

* Re: Ada OO Mechanism
  1999-05-26  0:00           ` Hyman Rosen
@ 1999-05-28  0:00             ` Laurent Guerby
  1999-06-01  0:00               ` Hyman Rosen
  0 siblings, 1 reply; 116+ messages in thread
From: Laurent Guerby @ 1999-05-28  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:
> No, you can not. There are tricks that can accomplish the test, but
> they are tricks, not basic language features. The C++ approach to
> generics is "if it compiles, it works". 

If I understand the rest of your posting, the C++ approach is "if it
links, it works". You have to wait the linker to complain about
mangled symbols not to be there to have the pleasure of trying to find
out where you messed up your template ;-).

> Instead of restricting a parameter to be of a certain type, you just
> write the template as if the parameter has that type. It may be that
> a different type will support the operations equally well, in which
> case there is no reason to prevent the template from working. I
> understand that this is unpleasant for many people who want to be
> able to say and see exactly what's going on with the code.

Strange, I would say that in Ada you doesn't have to know
"exactly what's going on with the code" inside your generic
to use and compile things, whereas in C++ you have to
see the template code to see if your parameters will
work. That's breaking some abstraction.

In Ada: "if it compiles against the spec it works, regardless of the
implementation". This favour distributed team work, properly
abstracted generic specs and so ease build large reliable stuff.

> In C++ as well. In C++, you use a template parameter -
> 
> template <typename T, int N> struct Array { T a[N]; }
> Array<int,5> ai;
> Array<double,10> ad;
> 
> Ada is somewhat ahead here, though, because (if I'm not mistaken)
> in Ada all the discrminated forms are the same type while in C++
> they're not (i.e., in C++, Array<int,5> and Array<int,6> are
> completely unrelated).

Interesting ;-). Also Ada programmers tend to have big generic
contracts (read lots of template arguments), I think the C++ notation
will tend to be cumbersome if one complex template instanciation type
is used a lot (well, you can #define then ;-).

> For objects at file scope in a single compilation unit (a file),
> constructors are called in top-to-bottom order. For static objects
> within a function, constructors are called the first time the flow
> of control passes through the definition. Order of initialization
> across compilation units is unspecified.

That was my point, unless you put everyting in a big C++ source file
you cannot build statically (at elaboration time in the Ada world)
complex objects implying multiple classes.

BTW, thanks for bringing your C++ expertise on us poor Ada guyes, I
really find your posts insightful on a lot of issues ;-).

--LG




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

* Re: Ada OO Mechanism
  1999-05-28  0:00                     ` Robert I. Eachus
  1999-05-28  0:00                       ` Brian Rogoff
@ 1999-05-29  0:00                       ` Ehud Lamm
  1999-05-30  0:00                         ` chris
  1999-06-03  0:00                         ` Matthew Heaney
  1 sibling, 2 replies; 116+ messages in thread
From: Ehud Lamm @ 1999-05-29  0:00 UTC (permalink / raw)


About double dispatching using class-wide paramters and run typme type
identifaction using 'tag:

I had a feeling this is what you are thinking about, since Ada like the
other languages I am familiar with doesn't go for double dispatching - nad
rightly so (try to define consistent semantics for such a thing).  However
using 'tag or other methods of RTTI (as are avaible in C++) is usually
concidred un-OOP, and not totally without reason. The argument is that if
you do manual checks for tags, you must change the code base when you
inherit, as opposed to simply coding new and sperate routines for the
overridden and new features of the new type. This is one of the problems
OOP tries to solve (you can see this discussed in many OOP books).  Some
OOP gurus even take the extreme view that almost any if/case statements in
a program indicate that the inheritance tree should be exapnded.

Ehud Lamm     mslamm@pluto.mscc.huji.ac.il





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

* Re: Ada OO Mechanism
  1999-05-29  0:00                       ` Ehud Lamm
@ 1999-05-30  0:00                         ` chris
  1999-05-30  0:00                           ` Robert Dewar
                                             ` (3 more replies)
  1999-06-03  0:00                         ` Matthew Heaney
  1 sibling, 4 replies; 116+ messages in thread
From: chris @ 1999-05-30  0:00 UTC (permalink / raw)


Today I saw a book on modula-3.

I think Ada OO should have been designed as modula-3 OO is.

In Modula-3, you have a modula, which is same as an Ada package.
but also, you have what is called an OBJECT, (which looked
like a RECORD), which contains DATA part, and METHODS part.

Inside a modula, you can declare an OBJECT.

So, here we have a language, which I thought was very similar to 
Ada, but used the familiar class like construct for the OO type.

I have no idea why Ada did not do it the same way. I wonder if when
Ada95 OO was designed, if modula-3 was around?

I liked the way modula-3 did it. I think I am going to learn more
about that language. Too bad it is not a very much used language.

chris.
 





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

* Re: Ada OO Mechanism
  1999-05-30  0:00                         ` chris
  1999-05-30  0:00                           ` Robert Dewar
@ 1999-05-30  0:00                           ` Harry George
  1999-05-30  0:00                             ` Vladimir Olensky
  1999-05-31  0:00                           ` Vladimir Olensky
  1999-06-01  0:00                           ` Richard D Riehle
  3 siblings, 1 reply; 116+ messages in thread
From: Harry George @ 1999-05-30  0:00 UTC (permalink / raw)


chris@nospam writes:

> Today I saw a book on modula-3.
> 
> I think Ada OO should have been designed as modula-3 OO is.
> 
[snip]
> 
> I have no idea why Ada did not do it the same way. I wonder if when
> Ada95 OO was designed, if modula-3 was around?
> 
From the home page (http://www.research.digital.com/SRC/modula-3/html/home.html):
   "Designed in the late 1980s at Digital
    Equipment Corporation and Olivetti"
 
> I liked the way modula-3 did it. I think I am going to learn more
> about that language. Too bad it is not a very much used language.

Amen.  A small but experienced community still uses it whereever
possible.  OO is just one of the things M3 does right.  We can only
hope Java steps up to UNSAFE and non-OO gc'd and non-gc'd structures.

> 
> chris.
>  
> 

-- 
Harry George
hgg9140@seanet.com




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

* Re: Ada OO Mechanism
  1999-05-30  0:00                         ` chris
@ 1999-05-30  0:00                           ` Robert Dewar
  1999-05-30  0:00                           ` Harry George
                                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 116+ messages in thread
From: Robert Dewar @ 1999-05-30  0:00 UTC (permalink / raw)


In article <7ircia$ued@drn.newsguy.com>,
  chris@nospam wrote:
> Today I saw a book on modula-3.
>
> I think Ada OO should have been designed as modula-3 OO is.
>
> So, here we have a language, which I thought was very similar
> to Ada, but used the familiar class like construct for the OO
> type.

> I have no idea why Ada did not do it the same way. I wonder if
> when Ada95 OO was designed, if modula-3 was around?

Yes, of course it was.

The thing to realize is that the design of Ada 95 is the way
it is not because someone didn't think of something, but on
the contrary because a lot of people thought a whole lot.

The key point in Ada is to provide orthogonal features that
can be used for many purposes. Some of these features are
modularity, information hiding, procedural abstraction, type
extension, inheritance and dynamic dispatching.

Yes, it is possible (and convenient) to use these for various
object oriented paradigms, but they are more general than this,
and are designed to be convenient to use in more general
circumstances.

For instance, take the example I mentioned, if you define an
algebra of operations on elements with operations such as
addition, then it makes good sense to use the notions of tagged
types, extensible types, inheritance and dynamic dispatching
to provide a definition that can be extended, e.g. a more
complex algebra can be developed which adds a multiplication
operation.

Now all this is expressible very nicely in Ada (I leave it as
an easy, though not trivial, excercise to write the code), but
it really does not make any sense to think of addition as a
method which sends messages to the elements thought of as
objects. This is a forced viewpoint that might have to be used
in other languages, but definition will not be helpful in
modeling an algebra, where the notion is a functional one,
rather than a procedural one with objects.

Note that in this case, the elements have no state, they are
just values.

Indeed you can take an entirely applicative view of this
construction in Ada without the slighest sense of procedural
thinking. Given that the notion of object is all about state
and sending messages that interact with this state, objects
are really quite inappropriate for this particular application.

In particular, this example cannot be programmed nearly as
neatly in Modula-3.



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Ada OO Mechanism
  1999-05-30  0:00                           ` Harry George
@ 1999-05-30  0:00                             ` Vladimir Olensky
  1999-05-31  0:00                               ` Robert Dewar
  0 siblings, 1 reply; 116+ messages in thread
From: Vladimir Olensky @ 1999-05-30  0:00 UTC (permalink / raw)



Harry George wrote in message ...
>chris@nospam writes:
>> I have no idea why Ada did not do it the same way. I wonder if when
>> Ada95 OO was designed, if modula-3 was around?
>>
>From the home page
(http://www.research.digital.com/SRC/modula-3/html/home.html):
>   "Designed in the late 1980s at Digital
>    Equipment Corporation and Olivetti"
>
>> I liked the way modula-3 did it. I think I am going to learn more
>> about that language. Too bad it is not a very much used language.
>
>Amen.  A small but experienced community still uses it whereever
>possible.  OO is just one of the things M3 does right.  We can only
>hope Java steps up to UNSAFE and non-OO gc'd and non-gc'd structures.


   M3 language definition was published in August 1988 and implemented soon
after that . In January 1989 some revisions were made to the language to
reflect the
experience of the M3 implementation.

So M3 is at least 6 years older than Ada 95.

M3 runs almost on all platforms (as Ada now).


    For me  use of UNSAFE  modules is very good approach  to provide program
reliability. Probably better  than imposing restriction everywhere as in
Ada.  The same
concept could be used in Ada 95 to relax restrictions where needed.

   In M3 you are not allowed to do unsafe operations  in usual modules (so
it is very restrictive there, in some cases much more restrictive than Ada)
but in UNSAFE modules you can do whatever you need. Isolating unsafe
operations in UNSAFE modules provide very good control over them.  Using
OPAQUE types you can build  safe interfaces to unsafe modules.

Another remarkable feature of  M3  is that it has Garbage Collector as part
of the
language specification. (Long before Java).

GB implementation was  successful and may be used as a good example.
If you don't want to use GB  any object  you may declare it as UNTRACED.

Several years ago developers of M3 founded company CMASS (www.cmass.com) to
build commercial version of  M3 and did some very impressive things (namely
Reactor - see below).

Unfortunately their efforts did not bring desired results due to different
factors.
Their story is a good lesson for others as well.

One of them is that at some moment  they took wrong direction putting all
their efforts  for building JVM using M3 that should work on every known
platform. They did that but priced it about $10000. So no wonder that they
could not compete with some known  big companies that did that for no money
for customer so  time and resources were  lost.


The other thing was that they thought that M3 is the best programming
language in the world (and it really was for very long period of time)  with
fully functional Garbage Collector and only this is enough to win (the same
as some people think regarding Ada now).

Another thing that had impact on M3 destiny was that for very, very long
period of time it was experimental language for closed community ( DEC SRC
and some other research centers)without no attempts to build and sell
commercial versions of M3.
   Any closed community in our world will shrink eventually if it do not
make efforts to expand.  As pressure from outside is almost always
increasing then pressure from inside should be adequate not to loose living
area. This is universal law. Earth history has illustrated this many times.
As time goes new  more perfect creatures come to existence that are pushing
away older ones.
But some lives forever without no changes (sharks, snakes, crocodiles).
Please note that these are creatures that are eating other creatures.  Hope
that Ada will live long as sharks.


One this in which CMASS M3 is still ahead of time is it's team development
system "Reactor".
It has central development server and any developer can do his/her work
from any workstation with WEB  browser.    Very impressive.

  In many respects Ada and M3 is very very close to each other. As Ada 95
was born later so  it has some other features that M3 does not have (e.g.
child packages). Ada 95 is a logical step for people who used M2 and M3
before.  By the way Averstar supports and sells extended version of Modula-2
called Modula-GM that is used by General Motors for car engine controllers.
A lot of people that use Ada do not even know that they  use Modula-GM as
well.

Regards,

Vladimir Olensky


















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

* Re: Ada OO Mechanism
  1999-05-30  0:00                         ` chris
  1999-05-30  0:00                           ` Robert Dewar
  1999-05-30  0:00                           ` Harry George
@ 1999-05-31  0:00                           ` Vladimir Olensky
  1999-06-03  0:00                             ` Dale Stanbrough
  1999-06-01  0:00                           ` Richard D Riehle
  3 siblings, 1 reply; 116+ messages in thread
From: Vladimir Olensky @ 1999-05-31  0:00 UTC (permalink / raw)


chris@nospam wrote in message <7ircia$ued@drn.newsguy.com>...
>
>In Modula-3, you have a modula, which is same as an Ada package.
>but also, you have what is called an OBJECT, (which looked
>like a RECORD), which contains DATA part, and METHODS part.
>
>Inside a modula, you can declare an OBJECT.
>
>So, here we have a language, which I thought was very similar to
>Ada, but used the familiar class like construct for the OO type.


==============================================

 As a matter of fact  M3 allows you to use both ways to invoke
methods on objects if my nemory serves me right.
----------------------------------------------------------------------------
------
--   Object.method  and method (object) are both valid calls for M3.
----------------------------------------------------------------------------
------
It just depends on the intention of the Interface  Module
designer who allows you to use  one of them or both (first one in most
cases).
Usually implementation modules use the method (object) syntax
but it is hidden from the user (as the implementation is not
visible to customer).

As M3 allows to have several different interfaces
to the same implementation module (exploiting so called
partial revelation) so it is possible to have  two
sets of operation (with different syntax) to be in the
different interfaces to given implementation as well.
M3 is extremely flexible regarding this.

Moreover, depending on how you defined your object methods
you may even allow user to redefine object methods during program
execution (just changing procedure address in VMT).
(e.g.during execution you can create array of bytes representing
some  chain of assembler instructions and then call it when needed).

It is just an example, more safe is to have object method which
can call any other procedure with the given profile.

If anyone have a look at M3 sources he/she can find there a lot of
extremely interesting things.
May be M3 experience will be considered seriously  some time in the future.

I wonder why Averstar sells and supports only Ada 95 and Modula-GM. It would
be logical to have M3 in the list of it's products .
It would be very impressive set: Ada 95, . AppletMagic, Modula-3, Modula-GM.

Regards,
Vladimir Olensky

Here some code from M3 sources  as an  illustration:
-------------------------------------

INTERFACE GO;

EXCEPTION PropUndefined;
EXCEPTION StackError;

TYPE
  Shape = {Complex, NonConvex, Convex, Unknown};

TYPE
  T <: Public;
  Public = ProxiedObj.T OBJECT
  METHODS
    init () : T;

   <stripped code>

    setName (name : TEXT);
    getName () : TEXT;

   <stripped code>

    pushMouseCB (cb : MouseCB.T);
    popMouseCB () RAISES {StackError};

   <stripped code>

  END;


----------------------------------------------------------------------------
----

Copyright (C) 1994, Digital Equipment Corp.
Created by Marc Najork

MODULE GO EXPORTS GO, GOPrivate;

  <stripped code>

REVEAL
  T = Private BRANDED OBJECT
  OVERRIDES
    init := Init;

    <stripped code>

    setName  := SetName;
    getName  := GetName;

    pushMouseCB   := PushMouseCB;
    popMouseCB    := PopMouseCB;

    <stripped code>

  END;

PROCEDURE Init (self : T) : T =
  BEGIN
    self.props   := NIL;
    self.damaged := TRUE;
    self.name    := NIL;
    self.dl      := 0;

    self.mouseCBstack    := NEW (MouseCBStack.T).init ();
    self.positionCBstack := NEW (PositionCBStack.T).init ();
    self.keyCBstack      := NEW (KeyCBStack.T).init ();

    RETURN self;
  END Init;


PROCEDURE SetName (self : T; name : TEXT) =
  BEGIN
    self.name := name;
  END SetName;

PROCEDURE GetName (self : T) : TEXT =
  BEGIN
    RETURN self.name;
  END GetName;

  <stripped code>

PROCEDURE PushMouseCB (self : T; cb : MouseCB.T) =
  BEGIN
    self.mouseCBstack.push (cb);
  END PushMouseCB;

PROCEDURE PopMouseCB (self : T) RAISES {StackError} =
  BEGIN
    self.mouseCBstack.pop ();
  END PopMouseCB;

  <stripped code>

BEGIN
  Transform := NEW (Transform_PN).init (Matrix4.Id);
END GO.

































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

* Re: Ada OO Mechanism
  1999-05-30  0:00                             ` Vladimir Olensky
@ 1999-05-31  0:00                               ` Robert Dewar
  0 siblings, 0 replies; 116+ messages in thread
From: Robert Dewar @ 1999-05-31  0:00 UTC (permalink / raw)


In article <928093666.328.83@news.remarQ.com>,
  "Vladimir Olensky" <vladimir_olensky@yahoo.com> wrote:

> Another remarkable feature of  M3  is that it has Garbage
> Collector as part of the language specification.
> (Long before Java).

Yes, it is surprising that some folks think Java was the first
strongly typed procedural language to require garbage collection
when M3 had appeared nearly ten years before

....

Almost as surprising as the fact that some folks thinking M3
was the first strongly typed procedural language to require
garbage collection when Algol-68 had appeared nearly 20 years
earlier :-)

And it is certainly fair to compare Algol-68 with Modula-3.
Actually A68 was really significantly more successful than
Modula-3. Two major manufacturers had fully supported Algol-68
compilers, and Algol-68 was very widely taught in England at
one stage (in the 1970 British Journal of Computing survey, it
was most mentioned as the ideal teaching language by British
respondents -- reflecting the availability of the excellent
ICL compiler).



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Ada OO Mechanism
  1999-05-30  0:00                         ` chris
                                             ` (2 preceding siblings ...)
  1999-05-31  0:00                           ` Vladimir Olensky
@ 1999-06-01  0:00                           ` Richard D Riehle
  3 siblings, 0 replies; 116+ messages in thread
From: Richard D Riehle @ 1999-06-01  0:00 UTC (permalink / raw)


In article <7ircia$ued@drn.newsguy.com>,
	chris@nospam wrote:

>Today I saw a book on modula-3.
>
>I think Ada OO should have been designed as modula-3 OO is.

 Modula-3 has some interesting ideas that could contribute to 
 future versions of Ada.  However, Modula-3, in its effort to
 keep the language simple, falls a little short of the strong
 typing we expect of a well-designed Ada 95 program.  

>In Modula-3, you have a modula, which is same as an Ada package.

 Well, actually, not the same.  There are some significant differences.
 Ada has a private part for the equivalent of an INTERFACE, and that
 increases the flexibility of the type model in terms of separate
 compilation of components of an implementation.  One may reasonably
 criticize this feature as being excessively complex, but it does
 increase one's options in developing software with Ada.

 On the other hand, those added options do make the development of
 compilers more complex.  The trade-off between compiler complexity
 and application programmer options raises issues that will not
 be easily agreed upon.  

>but also, you have what is called an OBJECT, (which looked
>like a RECORD), which contains DATA part, and METHODS part.

 While the Modula-3 approach to this is a little safer than
 the equivalent in C++, it still has weaknesses.  For example,
 if I understand correctly, there are still cases in which the
 compiler cannot determine if certain kinds of assignments are
 correct, and these can cause run-time faults.  

>Inside a modula, you can declare an OBJECT.
>
>So, here we have a language, which I thought was very similar to 
>Ada, but used the familiar class like construct for the OO type.

 Once again, we are seduced by the apparent simplicity of the 
     
             type <=> module <=> class   (OBJECT)

 On the surface, this simplicity is attractive.  In practice, it 
 leads to greater complexity than one might have expected.  This
 is certainly the case in C++.  Although I have not written Modula-3
 programs, my reading of the language description makes me suspect that
 some of the same problems from C++ will manifest themselves.  

>I have no idea why Ada did not do it the same way. I wonder if when
>Ada95 OO was designed, if modula-3 was around?

 The designers of Ada 95 knew about Modula-3.  The philosophy of the
 two languages is different.  Those who favor Modula-3 (I know some
 of them) tend to believe Ada is too full of features and favor a 
 smaller language definition.  For example, one author says "The
 rules associated with Ada generics are too complicated for our
 taste."  However, it is that set of rules that helps give Ada
 is unparalleled power in designing compile-time checked, generic
 reusable components.
 
>I liked the way modula-3 did it. I think I am going to learn more
>about that language. Too bad it is not a very much used language.

 Please do learn Modula-3 as thoroughly as possible.  Then return to 
 your assessment of Ada 95.  You may find yourself more charitable
 toward Ada. 

 The design of Ada was not a process of overlooking other language designs.
 It included careful analysis of what other languages had to offer. In
 fact, this one of the benefits of Ada 95 following the design of other
 languages.  The architects and reviewers of Ada 95 had the opportunity   to 
 evaluate how well certain features worked in other languages and the  
 option to incorporate those that seemed appropriate into the Ada 
 language design.  

 The decision to design Ada 95 as it is designed was a deliberate choice,
 for well-taken technical reasons.  One may disagree with those technical
 reasons, but they are as valid, in the end, as other choices that might
 have been made. 

 Richard Riehle
 richard@adaworks.com
 http://www.adaworks.com
 




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

* Re: Ada OO Mechanism
  1999-05-28  0:00             ` Laurent Guerby
@ 1999-06-01  0:00               ` Hyman Rosen
  1999-06-03  0:00                 ` Fraser Wilson
  0 siblings, 1 reply; 116+ messages in thread
From: Hyman Rosen @ 1999-06-01  0:00 UTC (permalink / raw)


Laurent Guerby <guerby@acm.org> writes:
> If I understand the rest of your posting, the C++ approach is "if it
> links, it works". You have to wait the linker to complain about
> mangled symbols not to be there to have the pleasure of trying to find
> out where you messed up your template ;-).

You give source code to the compiler, and it gives you either a working
executable, or a set of error messages explaining why it was unable to
do so. Internal phases of the compiler's operation are not of interest
to its user. If the error messages are unintelligible, then that is the
fault of the compiler author.

> Strange, I would say that in Ada you doesn't have to know
> "exactly what's going on with the code" inside your generic
> to use and compile things, whereas in C++ you have to
> see the template code to see if your parameters will
> work. That's breaking some abstraction.

In C++ you generally rely upon documentation of the template parameters
instead of actual restrictions, although it's possible to code those if
you want to. The C++ Standard has a vocabulary of some typical examples
(copy constructable, forward iterator, etc.).

> In Ada: "if it compiles against the spec it works, regardless of the
> implementation". This favour distributed team work, properly
> abstracted generic specs and so ease build large reliable stuff.

Probably so.

> Interesting ;-). Also Ada programmers tend to have big generic
> contracts (read lots of template arguments), I think the C++ notation
> will tend to be cumbersome if one complex template instanciation type
> is used a lot (well, you can #define then ;-).

You would use a typedef, not a #define. And most templates I've seen
have few parameters. Those with somewhat more tend to default the
later ones so that they may be elided.

> That was my point, unless you put everyting in a big C++ source file
> you cannot build statically (at elaboration time in the Ada world)
> complex objects implying multiple classes.

I'm not sure what you mean here - an example would be useful.

> BTW, thanks for bringing your C++ expertise on us poor Ada guyes, I
> really find your posts insightful on a lot of issues ;-).

I have never called anyone a "poor Ada guy", nor have I stated that
C++ is a better language than Ada.




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

* Re: Ada OO Mechanism
  1999-06-03  0:00                             ` Dale Stanbrough
@ 1999-06-02  0:00                               ` mike
  1999-06-03  0:00                                 ` Robert Dewar
  0 siblings, 1 reply; 116+ messages in thread
From: mike @ 1999-06-02  0:00 UTC (permalink / raw)


In article <dale-0306991131040001@dale.cs.rmit.edu.au>, dale@cs.rmit.edu.au
says...
>
>Vladimir Olensky wrote:
>
>[some sample Modula-3 code]
>

>
>I just remembered on seeing the code that Modula-3 requires 
>reserved words to be in upper case. This would surely make
>Mike Feldman happy! :-)
>
>
 

I setup my emacs Ada mode so that it makes keywords upper case also :)

I always found it easier to read code like that. I even used to
have a header file for my C/C++ code that does:


#define WHILE while
#define DO    do
#define BEGIN {
#define END    }
#define FOR    for
#define IF     if
#define ELSE   else

etc.. 

which made my C/C++ more pleasent for me to work one, and more
readable. 

Mike





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

* Re: Ada OO Mechanism
  1999-06-01  0:00               ` Hyman Rosen
@ 1999-06-03  0:00                 ` Fraser Wilson
  0 siblings, 0 replies; 116+ messages in thread
From: Fraser Wilson @ 1999-06-03  0:00 UTC (permalink / raw)


paene lacrimavi postquam Hyman Rosen <hymie@prolifics.com> scripsit:

>You give source code to the compiler, and it gives you either a working
>executable, or a set of error messages explaining why it was unable to
>do so. Internal phases of the compiler's operation are not of interest
>to its user.

I disagree with this.  One of the things I like about Ada is not having
to wait until link time to find out that I forgot to implement a subprogram.
It's not just a time factor; the Ada compiler will tell me exactly which
package(s) failed to contain the required implementation; all the C or
C++ compiler can say is that it didn't find something.

It's even worse if, for example, a C or C++ library was written by somebody
else, and that person neglected to implement something, but testing never
picked it up because it was never called.

>You would use a typedef, not a #define. And most templates I've seen
>have few parameters. Those with somewhat more tend to default the
>later ones so that they may be elided.

Really?  I can imagine that a large template would be tricky in C++,
but it's straightforward in Ada (especially with named argument notation),
and surprisingly useful.  One particularly handy generic I wrote has 28
parameters ... I'd hate to see that attempted in a less wordy language.
Sure, I make new instantiations of it with a bit of cut and paste, but
it's really really easy to read, maintain and update.

cheers,
Fraser.
(change i's to y's for my real email address)




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

* Re: Ada OO Mechanism
  1999-06-02  0:00                               ` mike
@ 1999-06-03  0:00                                 ` Robert Dewar
  1999-06-06  0:00                                   ` David Botton
  0 siblings, 1 reply; 116+ messages in thread
From: Robert Dewar @ 1999-06-03  0:00 UTC (permalink / raw)


In article <7j4nro$1ft@drn.newsguy.com>,
  mike@nospam wrote:
> which made my C/C++ more pleasent for me to work one, and more
> readable.
>

This kind of thing is VERY bad style. One of the primary
things that you should consider in writing code is to make
it pleasant for OTHERS to work on and read. Adopting
non-standard idiosyncratic styles (your C/C++ example, if
not intended as a joke, is an extreme example), is in the
worst tradition of deliberate code obfuscation.

Conformity to both formal and informal standards in programming
is an important part of good style.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Ada OO Mechanism
  1999-05-24  0:00   ` Hyman Rosen
  1999-05-24  0:00     ` Robert Dewar
  1999-05-25  0:00     ` Samuel Mize
@ 1999-06-03  0:00     ` Matthew Heaney
  1999-06-03  0:00       ` Hyman Rosen
  2 siblings, 1 reply; 116+ messages in thread
From: Matthew Heaney @ 1999-06-03  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:

> Samuel Mize <smize@imagin.net> writes:
> > There are other OO design approaches that are harder to implement in
> > C++ than in Ada, because C++ strongly supports one specific view of
> > object-oriented technology.
> 
> Could you give an example of this?


  type Human_Type (<>) is tagged limited private;

  ...

  procedure Marry (Bride, Groom : in out Human_Type);


This is a binary operation:

  Marry (Linda, Paul);


The operation applies equally to both parties, so designating one object
as the distinguished receiver would not capture the abstraction as well.






   




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

* Re: Ada OO Mechanism
  1999-05-25  0:00                   ` Hyman Rosen
                                       ` (2 preceding siblings ...)
  1999-05-28  0:00                     ` Robert I. Eachus
@ 1999-06-03  0:00                     ` Matthew Heaney
  3 siblings, 0 replies; 116+ messages in thread
From: Matthew Heaney @ 1999-06-03  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:

> So you mean in Ada, I can write a dot(a,b) which will dispatch on
> either a or b?

Yes, if A and B have the same specific type. 

    <types AT and BT derive from T>

    A1, A2 : AT;
    B1, B2 : BT;

    AC1, AC2 : T'Class := <object has type AT>;
    BC1, BC2 : T'Class := <object has type BT>;

  begin
    
   .. := Dot (A, B);    -- illegal, detected at compile-time

         Dot (A1, A2);  -- legal
         Dot (B1, B2);  -- legal

         Dot (AC1, AC2);  -- legal, tags compared at run-time
         Dot (BC1, BC2);  -- legal, tags compared at run-time

         Dot (AC1, BC1);  -- legal, but run-time tag check fails,
                          -- and Constraint_Error is raised
  end;





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

* Re: Ada OO Mechanism
  1999-05-29  0:00                       ` Ehud Lamm
  1999-05-30  0:00                         ` chris
@ 1999-06-03  0:00                         ` Matthew Heaney
  1 sibling, 0 replies; 116+ messages in thread
From: Matthew Heaney @ 1999-06-03  0:00 UTC (permalink / raw)


Ehud Lamm <mslamm@mscc.huji.ac.il> writes:

> However using 'tag or other methods of RTTI (as are avaible in C++) is
> usually concidred un-OOP, and not totally without reason. The argument
> is that if you do manual checks for tags, you must change the code
> base when you inherit, as opposed to simply coding new and sperate
> routines for the overridden and new features of the new type.

Not necessarily.  It may be the case the you're using 'Tag simply to
make sure the tags are the same.










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

* Re: Ada OO Mechanism
  1999-05-31  0:00                           ` Vladimir Olensky
@ 1999-06-03  0:00                             ` Dale Stanbrough
  1999-06-02  0:00                               ` mike
  0 siblings, 1 reply; 116+ messages in thread
From: Dale Stanbrough @ 1999-06-03  0:00 UTC (permalink / raw)


Vladimir Olensky wrote:

[some sample Modula-3 code]


I just remembered on seeing the code that Modula-3 requires 
reserved words to be in upper case. This would surely make
Mike Feldman happy! :-)


Dale




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

* Re: Ada OO Mechanism
  1999-06-03  0:00     ` Matthew Heaney
@ 1999-06-03  0:00       ` Hyman Rosen
  0 siblings, 0 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-06-03  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> writes:
>   type Human_Type (<>) is tagged limited private;
>   procedure Marry (Bride, Groom : in out Human_Type);
> This is a binary operation:
>   Marry (Linda, Paul);
> The operation applies equally to both parties, so designating one object
> as the distinguished receiver would not capture the abstraction as well.

I see. I think at this point, C++ programmers would have to code the
tag test themselves, but then the usage would look very similar.

struct Human_Type
{
        friend Marry(Human_Type &a, Human_Type &b)
        {
                if (typeid(a) != typeid(b))
                        throw "Marriage of unequals!";
                a.Marry(b);
        }
private:
	virtual void Marry(Human_Type &other) = 0;
};

struct Lord : Human_Type
{
private:
	virtual void Marry(Human_Type &other)
	{
                Lord &other_lord = static_cast<Lord &>(other);
                //...
	}
};





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

* Re: Ada OO Mechanism
  1999-05-26  0:00                                 ` Hyman Rosen
  1999-05-27  0:00                                   ` Richard D Riehle
  1999-05-28  0:00                                   ` Laurent Guerby
@ 1999-06-05  0:00                                   ` Matthew Heaney
  1999-06-07  0:00                                     ` Hyman Rosen
  2 siblings, 1 reply; 116+ messages in thread
From: Matthew Heaney @ 1999-06-05  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:

> From a little fooling around with your code above and gnat, and the
> Rationale, it looks like the compiler has to examine the code that
> attempts to initialize a T'Class variable and allocate the maximum
> space for it that that code would require.

No.  The compiler has no way of knowing at compile-time how much space
to allocate on the stack for the return value of the function.  The size
is determined at run-time.

This is how factory methods work:

  procedure Print (Q : in Queue'Class) is 

    Iter : Iterator'Class := Get_Iter (Q);  
    --
    -- Iter goes on the stack (not the heap), and its size is 
    -- determined at run-time.

  begin















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

* Re: Ada OO Mechanism
  1999-05-27  0:00                                   ` Richard D Riehle
@ 1999-06-05  0:00                                     ` Matthew Heaney
  1999-06-07  0:00                                       ` Hyman Rosen
  0 siblings, 1 reply; 116+ messages in thread
From: Matthew Heaney @ 1999-06-05  0:00 UTC (permalink / raw)


Richard D Riehle <laoXhai@ix.netcom.com> writes:

>  Now for the bad news.  Ada access parameters allow the programmer
>  to violate the encapsulation too.  Although the access parameter
>  itself is regarded as an in parameter in Ada, 

No.  An access parameter is an in out param, that automatically
dereferences a pointer.  

An access parameter is used to implement by-reference abstractions:

  type T (<>) is tagged limited private;

  procedure Op (O : access T);


Singletons that are instances of a type are written this way:

  package Mazes.Games is

    type Maze_Type (<>) is limited private;

    type Maze_Access is access all Maze_Type;

    function Maze return Maze_Access;

    function Get_Room 
      (Maze   : access Maze_Type;
       Number : in     Room_Number) return Room_Access;

  ...
  end Mazes.Games;


So a client would just say:

   Room : constant Room_Access := Get_Room (Maze, 2);
                                            ^^^^

Access parameters give Ada reference-semantics, without the syntactic
overhead (having to say .all everywhere).

There are many examples of this idiom in the ACM patterns archive:

<http://www.acm.org/archives/patterns.html>


>  a programmer may dereference data being referenced, if there is
>  visibility to the data.

Yes, but in the current version of Ada, an access parameter is really an
in out parameter.

You are correct in pointing out that there are times when an operation
doesn't need to modify the state of the object, even though it takes an
access parameter.  

But I don't buy the argument that this makes all kinds of abuse
possible.  A client can only manipulate an abstraction using the
(primitive) operations provided.  

And the writer of an abstraction has visibility to the implementation
anyway.  He's not going to suddenly go berserk, arbitrarily changing
state, just because one of the operations happens to take an access
param instead of an access constant param.


>  In this regard, I think C++ is a little stronger because of the
>  option of const functions and const parameters.  My preference for a
>  future addition to the Ada standard would be some kind of constant
>  function such as,
> 
>     constant function F (A : access some-type) return T;
> 
>  or, closer to C++,
> 
>     function F (A : constant access some-time) return T;
> 
>  which would disallow any monkey business with the function. 

The more likely scenario will be:

  procedure Op (O : access constant T);

  function Op (O : access constant T) return Item;

This was considered for Ada95 but didn't make the cut, because the
language designers were trying to keep the number of language changes
small.  

In this respect, C++ is superior to Ada95, but not for the reasons you
argue.


>  In fact, this would correspond to the notion of a query with no
>  possible side-effects (much like the protected type function) and
>  satisfy Bertrand Meyer's insistence that queries should only query
>  and modifiers should only modify.

Then I disagree with Bertrand (what else is new).  From a specification
point of view, a selector might not be state-changing, but there may be
very good reasons to make an internal state-change.

For example, one might wish to record how many times a certain function
was invoked.  "Casting away const" is a useful, and necessary, feature.

 
>  This is one feature of Ada, for object-oriented programming where
>  I think C++ is a little stronger.  

The problem with Ada is that it doesn't separate interface from
implementation enough.  The parameter modes that appear in a spec apply
to the body too - but why?  

For example, there's no easy way to write the function I mentioned
above:

  function Get_Item (O : in T) return Item_Type;

Now how am I supposed to record that Get_Item got invoked?  T has mode
in, not in out, so I can't easily change O's state.

Suppose I had in out function params:

  function Get_Item (O : in out T) return Item_Type;

This would solve my problem, but it's still advertising more than I
really wish to advertise.  Why does the client care that O is in out?
(He doesn't.)  I only needed to state that in the spec, because it's
what I need to do in the body.

 
> >It is a fallacy that friend functions break encapsulation. Friendship
> >is granted explicitly by a class. These friends are part of the
> >encapsulation. 
> 
>  Friends are "part of the encapsulation", but also seem, to me, to be
>  an awkward feature included to compensate for problems associated
>  with the   class <=> type <=> module   model.   Without this kind
>  of model, the notion of friends would be unnecessary.     

Yes.  You need friend because the type and mode were coupled.  In Ada,
visibility is controlled by the module feature, which is separate from
the type feature, which means a friend feature isn't necessary.

The "bad" thing about the friend construct is not that it violates
information hiding; after all, child packages and co-declarations allow
you to "violate" information hiding too.  The issue is that you can't
extend visibility from one abstraction to another without paying a
compilation penalty.


> >Mutable has nothing at all to do with this - mutable
> >members of an object may be modified even when the object is declared
> >to be 'const'. The intent is to provide a difference between logical
> >constness and physical constness. For example, one would expect that
> >the characters of a const string would never change, but there could
> >be an internal reference count that needs adjustment. That count would
> >be declared mutable.
> 
>  I understand that mutable is a feature for reversing const'ness. We
>  have in Ada the notion of a general access constant that satisfies
>  the situation you mention, if I understand your explanation.  It just
>  seems, once again, that this is an add-on to compensate for a language
>  weakness rather than a coherent part of the overall design.  

Don't agree.  This is a feature we don't have in Ada, and it is sorely
missed.

What we have to do now, in order to create a physical state-change in an
object during an operation that is logically constant is:

  1) make sure the type is a by-reference type, per RM95 6.2 (4)
  
  2) take its address, per RM95 13.3 (16)

  3) convert the address to an access-to-variable, per RM95 13.7.2

This is a royal pain in the ass.  Worse, by having to go through an
intermediate Address, we throw all type-checking out the window, which
makes errors all the more likely.  In effect, it reduces to a C program.

Thankfully, gnat has 'Unrestricted_Access, which preserves all type
checking, but this feature in non-portable.

An example is the implementation of function Random:

  function Random (G : in Generator) return Uniformly_Distributed;

See the files (especially the Implementation Note) 

  a-nudira.ad?
  a-nuflra.ad?

in the gnat sources for an example.

There are many example of using Address_To_Access_Conversions in the ACM
patterns archive, to get around these limitations in the language.  

<http:www.acm.org/archives/patterns.html>


> >For completeness sake, class member templates *can* be used to break
> >encapsulation. The C++ philosophy is to protect encapsulation against
> >Murphy but not Machiavelli.

The same is true in Ada95, via the child mechanism.  You need a way to
efficiently extend an abstraction, and this often requires extending
visibility to the implementation.

Both languages have satisfied the need, but by using different
mechanisms.  The benefit of the Ada way is that there is no compilation
penalty.









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

* Re: Ada OO Mechanism
  1999-06-03  0:00                                 ` Robert Dewar
@ 1999-06-06  0:00                                   ` David Botton
  1999-06-07  0:00                                     ` Robert Dewar
  0 siblings, 1 reply; 116+ messages in thread
From: David Botton @ 1999-06-06  0:00 UTC (permalink / raw)


Yes, but possibly his project standardized on this alternate
representation. Then this would be conformity, good style and readable
:)

David Botton


Robert Dewar wrote:
> 
> In article <7j4nro$1ft@drn.newsguy.com>,
>   mike@nospam wrote:
> > which made my C/C++ more pleasent for me to work one, and more
> > readable.
> >
> 
> This kind of thing is VERY bad style. One of the primary
> things that you should consider in writing code is to make
> it pleasant for OTHERS to work on and read. Adopting
> non-standard idiosyncratic styles (your C/C++ example, if
> not intended as a joke, is an extreme example), is in the
> worst tradition of deliberate code obfuscation.
> 
> Conformity to both formal and informal standards in programming
> is an important part of good style.
> 
> Sent via Deja.com http://www.deja.com/
> Share what you know. Learn what you don't.




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

* Re: Ada OO Mechanism
  1999-06-06  0:00                                   ` David Botton
@ 1999-06-07  0:00                                     ` Robert Dewar
  0 siblings, 0 replies; 116+ messages in thread
From: Robert Dewar @ 1999-06-07  0:00 UTC (permalink / raw)


In article <375A8197.5DAB7C57@Botton.com>,
  David Botton <David@Botton.com> wrote:
> Yes, but possibly his project standardized on this alternate
> representation. Then this would be conformity, good style and
readable
> :)

Well I know there is a smiley here, but just so there is
no confusion in my thinking, a project that standardized
on such a NON-standard way of doing things would me making
a very serious mistake.

One of the important tasks of any project is to try to make
sure that your code is written in a way that people generally
familiar with your technology will be able to easily understand
and maintain.

For example, I consider the important thing about the GNAT code
not that people in the GNAT project find it easy to read here
at ACT, but that all sorts of people OUTSIDE the GNAT project
have commented that it was easy to read.

If we used some kind of bizarre non-standard way of doing
things (say upper case keywords and text indented in the
opposite direction from usual, and semicolons at the beginning
of each line instead at the end), I don't think we would
get this reaction.

        PROCEDURE horrible is
     x : integer
    ;y : integer
    ;BEGIN
  NULL
    ;END
    ;

(even if we followed this style rigourously :-)

Using Pascal style keywords in C programs is almost as bad
a transgression of normal coding standards in C!



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Ada OO Mechanism
  1999-06-05  0:00                                   ` Matthew Heaney
@ 1999-06-07  0:00                                     ` Hyman Rosen
  1999-06-08  0:00                                       ` Robert Dewar
  1999-06-08  0:00                                       ` Matthew Heaney
  0 siblings, 2 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-06-07  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> writes:
> No.  The compiler has no way of knowing at compile-time how much space
> to allocate on the stack for the return value of the function.  The size
> is determined at run-time.

From a little further fooling around, followed by a trip to the Ada RM,
I see that objects of class-wide type can not be record components, which
I guess makes sense, but it doesn't seem very orthogonal to me.




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

* Re: Ada OO Mechanism
  1999-06-05  0:00                                     ` Matthew Heaney
@ 1999-06-07  0:00                                       ` Hyman Rosen
  0 siblings, 0 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-06-07  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> writes:
> The "bad" thing about the friend construct is not that it violates
> information hiding; after all, child packages and co-declarations allow
> you to "violate" information hiding too.  The issue is that you can't
> extend visibility from one abstraction to another without paying a
> compilation penalty.

And you mention compilation penalty again later. What do you mean?




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

* Re: Ada OO Mechanism
       [not found]                           ` <t7zp2sr6yf.fsf@calumny.jyacc.c <t7r9nmz8ou.fsf@calumny.jyacc.com>
@ 1999-06-08  0:00                             ` Larry Kilgallen
  1999-06-08  0:00                               ` Hyman Rosen
  0 siblings, 1 reply; 116+ messages in thread
From: Larry Kilgallen @ 1999-06-08  0:00 UTC (permalink / raw)


Reply-To: Kilgallen@eisner.decus.org.nospam
Organization: LJK Software
Lines: 21

In article <t7r9nmz8ou.fsf@calumny.jyacc.com>, Hyman Rosen <hymie@prolifics.com> writes:
> kilgallen@eisner.decus.org (Larry Kilgallen) writes:
>> The fact that GNAT allocates it in one place does not mean all compilers
>> will do it in the same place.  Is your question specifically "how does
>> GNAT do this ?" ?
> 
> I am trying to understand the mechanism behind T'Class. I have been told
> that the size of such variables is determined at run-time, and also that
> the heap is not required for such variables.

If your compiler stores it entirely on the stack, the heap is not required.
Obviously some compiler could store it on the heap, in which case the
statement "all compilers store it entirely on the stack" would be wrong.

At a more basic level, storing a variable length structure on the stack
requires that the machine code alter the amount of stack consumed on
one call from the next.  Many other languages do not have programmer-
visible constructs that do such a run-time determination, so perhaps
that is what makes the concept seem strange.

Larry Kilgallen




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                               ` Hyman Rosen
@ 1999-06-08  0:00                                 ` Tucker Taft
  1999-06-08  0:00                                   ` Brian Rogoff
                                                     ` (3 more replies)
  1999-06-09  0:00                                 ` Matthew Heaney
  1999-06-09  0:00                                 ` Samuel Mize
  2 siblings, 4 replies; 116+ messages in thread
From: Tucker Taft @ 1999-06-08  0:00 UTC (permalink / raw)


Hyman Rosen wrote:
> 
> kilgallen@eisner.decus.org (Larry Kilgallen) writes:
> > The fact that GNAT allocates it in one place does not mean all compilers
> > will do it in the same place.  Is your question specifically "how does
> > GNAT do this ?" ?
> 
> I am trying to understand the mechanism behind T'Class. I have been told
> that the size of such variables is determined at run-time, and also that
> the heap is not required for such variables.
> 
> So, to anyone, if you don't mind taking the time to explain, how does
> <compiler of your choice> implement this?

Several compilers use what is called a "secondary stack" (or a "data stack"),
as distinct from the "primary stack" (or "control stack").
The secondary stack is generally managed in a mark/release manner.
There is one per task.  On entry to a subprogram or block the
secondary stack is marked, and prior to exit, the secondary stack is
released.  In the interim objects of run-time-determined size may
be allocated as needed.  A pointer to the object is generally stored
on the primary stack.

For functions that return objects of size unknown to the caller, the
function creates the object on (or copies the object to) the secondary
stack, and then returns from the function *without* releasing the
secondary stack.  The caller takes care of releasing the secondary stack
once they are through with using the returned object.

There are other compilers that use "local" heaps, or other heap-based
mechanisms.  They all still typically use some kind of mark/release,
though it may be a mark/release on a linked-list of objects, rather
than on a secondary stack.

> 
> Also, I stated in an earlier message that I thought not allowing T'Class
> variables in records was not orthogonal, but understandable in light of
> the above. Now, suppose I need a function that returns a pair of values,
> one of which is a T'Class and the other a boolean. Is there a way to do
> this? I can't return a record containing the pair, because I can't have
> such a record. I assume that a procedure with a pair of out parameters
> won't work, because the T'Class variable which receives the output must
> be initialized when declared, and then its tag can't change. So, is there
> a way?

No.  Once you need to combine a class-wide value with something else,
you will have to use the heap explicitly.  (I suppose you could
add an "access Boolean" parameter to a function if you wanted to return
a Boolean as well as a class-wide value.)

As pointed out by Markus Kuhn, Ada goes one (important, in my mind) step
beyond C/C++ by providing built-in, safe support for objects whose size
is not known at compile-time.  However this support is not completely
flexible -- it is generally restricted to cases where the size is known
at the time when the object is declared. Explicit use of the heap is the 
fallback approach when you need more flexibility than is directly supported.
-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                 ` Tucker Taft
@ 1999-06-08  0:00                                   ` Brian Rogoff
  1999-06-09  0:00                                   ` Robert Dewar
                                                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 116+ messages in thread
From: Brian Rogoff @ 1999-06-08  0:00 UTC (permalink / raw)


On Tue, 8 Jun 1999, Tucker Taft wrote:
> Hyman Rosen wrote:
> > Also, I stated in an earlier message that I thought not allowing T'Class
> > variables in records was not orthogonal, but understandable in light of
> > the above. Now, suppose I need a function that returns a pair of values,
> > one of which is a T'Class and the other a boolean. Is there a way to do
> > this? I can't return a record containing the pair, because I can't have
> > such a record. I assume that a procedure with a pair of out parameters
> > won't work, because the T'Class variable which receives the output must
> > be initialized when declared, and then its tag can't change. So, is there
> > a way?
>
> No.  Once you need to combine a class-wide value with something else,
> you will have to use the heap explicitly.  (I suppose you could
> add an "access Boolean" parameter to a function if you wanted to return
> a Boolean as well as a class-wide value.)

This kind of problem is solved in some languages, like Common Lisp and 
Dylan, with multiple value return and others, like ML and Haskell, with
tuples. Was the prospect of such a mechanism for Ada considered (yes I'm
sure :-) and if so why was it rejected? Seeing as Ada has aggregates, it
seems to me that multiple value return would also have been a feature. 

Using access params here to simulate functions with out params looks really
ugly to me. 

-- Brian






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

* Re: Ada OO Mechanism
  1999-06-07  0:00                                     ` Hyman Rosen
@ 1999-06-08  0:00                                       ` Robert Dewar
  1999-06-08  0:00                                         ` Markus Kuhn
  1999-06-08  0:00                                         ` Stanley R. Allen
  1999-06-08  0:00                                       ` Matthew Heaney
  1 sibling, 2 replies; 116+ messages in thread
From: Robert Dewar @ 1999-06-08  0:00 UTC (permalink / raw)


In article <t7wvxfn75v.fsf@calumny.jyacc.com>,
  Hyman Rosen <hymie@prolifics.com> wrote:
> From a little further fooling around, followed by a trip to
the Ada RM,
> I see that objects of class-wide type can not be record
components, which
> I guess makes sense, but it doesn't seem very orthogonal to
me.


Actually it is quite orthogonal and consistent with the
rest of the language. X'Class is like String from this point
of view, it is a general type, and you need a specific instance
to declare an object or a record component of this type.

There is another language that you might see here in which
String variables are generally permitted, and in that language
you would also expect to find X'Class record components (as
well as automatic storage management, and a generally rather
different semantic level).



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Ada OO Mechanism
  1999-06-07  0:00                                     ` Hyman Rosen
  1999-06-08  0:00                                       ` Robert Dewar
@ 1999-06-08  0:00                                       ` Matthew Heaney
  1999-06-08  0:00                                         ` Hyman Rosen
  1 sibling, 1 reply; 116+ messages in thread
From: Matthew Heaney @ 1999-06-08  0:00 UTC (permalink / raw)


On 07 Jun 1999 15:26:52 -0400, Hyman Rosen <hymie@prolifics.com> wrote:

> Matthew Heaney <matthew_heaney@acm.org> writes:
> > No.  The compiler has no way of knowing at compile-time how much space
> > to allocate on the stack for the return value of the function.  The size
> > is determined at run-time.
> 
> From a little further fooling around, followed by a trip to the Ada RM,
> I see that objects of class-wide type can not be record components, which
> I guess makes sense, but it doesn't seem very orthogonal to me.

I'm not sure what you mean by "doesn't seem very orthogal," but there
are pragmatic reasons for not allowing a class-wide type as a record
component.

Just as the record decl 

  type RT is
    record
      S : String;
    end record;


is illegal, so is the decl

  type RT is
    record
      O : T'Class;
    end record;


However, the declaration

  declare
    S : String := Func_Return_String;
  begin


is perfectly legal, and so is the declaration

  declare
    O : T'Class := Func_Return_T_Tic_Class;
  begin
  


In neither case is heap required.





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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                       ` Robert Dewar
@ 1999-06-08  0:00                                         ` Markus Kuhn
  1999-06-08  0:00                                           ` Stanley R. Allen
  1999-06-08  0:00                                         ` Stanley R. Allen
  1 sibling, 1 reply; 116+ messages in thread
From: Markus Kuhn @ 1999-06-08  0:00 UTC (permalink / raw)


Robert Dewar <robert_dewar@my-deja.com> writes:
|> In article <t7wvxfn75v.fsf@calumny.jyacc.com>,
|>   Hyman Rosen <hymie@prolifics.com> wrote:
|> > From a little further fooling around, followed by a trip to the Ada RM,
|> > I see that objects of class-wide type can not be record components, which
|> > I guess makes sense, but it doesn't seem very orthogonal to me.
|> 
|> There is another language that you might see here in which
|> String variables are generally permitted, and in that language
|> you would also expect to find X'Class record components (as
|> well as automatic storage management, and a generally rather
|> different semantic level).

This is exactly an example of what makes Ada so fascinating but also
so challenging to thoroughly understand for a beginner. We have on one
side simple low-level languages such as C, where the memory
representation of objects is fairly completely visible to the programmer
and where it is easy to realize what is going on behind the scenes.
On the other hand, we have very high level languages with garbage
collection such as Lisp, Scheme, Perl, Python, to some degree also
Java. They hide completely from the programmer issues such as memory
management and memory layout, they provide a very simple form of
orthogonality (everything can contain anything), but they are because
of these properties unsuitable for high-performance, low-level, real-time,
and safety-critical programming. Ada goes a very rarely seen path in
between these clearly separated communities. On one side it is a
low-level language such as C that gives the programmer tight control over
various representation issues and results in high-performance code. On
the other hand it has features such as unconstrained arrays and functions
that return variable-length objects that resemble closely more powerful
features of real high-level languages such as Scheme and Python, but that
are still implementable without the need of a garbage collector or
a byte-code interpreter.

Experienced programmers know a lot about how languages like C and Scheme
work below the hood, but since Ada is somewhere in between, this can at
first be rather confusing. Unfortunatelly, none of the textbooks
about Ada talk enough about how these features (especially
variable-length arrays, types with discriminators, subtypes, etc.) that
are not seen much in other languages are usually implemented by
compilers.

I hope that one day, somebody will write an Ada textbook, that does not just
state the various rules of the lannguage (which can be very difficult to
remember), but that explains features such as types with discriminators
and fucntions returning variable-length arrays based on examples how
common compilers such as GNAT implement these. Then the restrictions
of these mechanisms will become obvious and have not to be remembered
as a seemingly non-orthogonal set of rules. A good paper on how GNAT
implements all the features of Ada that are not obvious for a C
programmer would also be a very important teaching tool in this
respect. Is there anything comparable already available?

Markus

-- 
Markus G. Kuhn, Computer Laboratory, University of Cambridge, UK
Email: mkuhn at acm.org,  WWW: <http://www.cl.cam.ac.uk/~mgk25/>




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                       ` Robert Dewar
  1999-06-08  0:00                                         ` Markus Kuhn
@ 1999-06-08  0:00                                         ` Stanley R. Allen
  1 sibling, 0 replies; 116+ messages in thread
From: Stanley R. Allen @ 1999-06-08  0:00 UTC (permalink / raw)


Robert Dewar wrote:
> 
> There is another language that you might see here in which
> String variables are generally permitted, and in that language
> you would also expect to find X'Class record components (as
> well as automatic storage management, and a generally rather
> different semantic level).
> 

Nothing but a tease!

-- 
Stanley Allen
mailto:s_allen@hso.link.com




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                         ` Markus Kuhn
@ 1999-06-08  0:00                                           ` Stanley R. Allen
  0 siblings, 0 replies; 116+ messages in thread
From: Stanley R. Allen @ 1999-06-08  0:00 UTC (permalink / raw)


Markus Kuhn wrote:
> 
> Unfortunatelly, none of the textbooks
> about Ada talk enough about how these features (especially
> variable-length arrays, types with discriminators, subtypes, etc.) that
> are not seen much in other languages are usually implemented by
> compilers.
> 
> I hope that one day, somebody will write an Ada textbook, that does not just
> state the various rules of the lannguage (which can be very difficult to
> remember), but that explains features such as types with discriminators
> and fucntions returning variable-length arrays based on examples how
> common compilers such as GNAT implement these. Then the restrictions
> of these mechanisms will become obvious and have not to be remembered
> as a seemingly non-orthogonal set of rules. 

The implementation of some of these features may be useful to explain
their use, but making the philosphy behind them more apparent may be
the real need.  There is, lurking under the "surface" rules of the Ada
language, a more or less thoroughly worked out collection of design
principles.  The orthogonality of the language can only be seen
by comprehending these principles.  The issue that triggered this
response -- the similar rules for unconstrained types and class-wide
types ("indefiniteness") -- is an example of one of these hidden
principles at work.  When I teach the language, I always try to make
such principles explicit.

Subtypes, generic formal and actual matching rules, type attributes,
staticness, and the relationship between elaboration and execution --
are are topics that "fall between the cracks" sometimes, but are essential
to grasp in order to make the most effective use of the language.

(Speaking of orthogonality, one can only speculate -- unless Mr. Taft
addresses it his memoirs one day -- on the influence that the science of
chemistry has had on the design of Ada 95.  Perhaps even unconsciously
so??... ;)

-- 
Stanley Allen
mailto:s_allen@hso.link.com




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

* Re: Ada OO Mechanism
       [not found]                           ` <t7zp2sr6yf.fsf@calumny.jyacc.c <t7emjmmx8w.fsf@calumny.jyacc.com>
@ 1999-06-08  0:00                             ` Larry Kilgallen
  1999-06-08  0:00                               ` Hyman Rosen
  0 siblings, 1 reply; 116+ messages in thread
From: Larry Kilgallen @ 1999-06-08  0:00 UTC (permalink / raw)


Reply-To: Kilgallen@eisner.decus.org.nospam
Organization: LJK Software
Lines: 25

In article <t7emjmmx8w.fsf@calumny.jyacc.com>, Hyman Rosen <hymie@prolifics.com> writes:
> Matthew Heaney <matthew_heaney@acm.org> writes:
>> On 07 Jun 1999 15:26:52 -0400, Hyman Rosen <hymie@prolifics.com> wrote:
>> However, the declaration
>>   declare
>>     S : String := Func_Return_String;
>>   begin
>> is perfectly legal, and so is the declaration
>>   declare
>>     O : T'Class := Func_Return_T_Tic_Class;
>>   begin
>> In neither case is heap required.
> 
> And despite that, you said before that the size of O is determined
> at run-time, not at compile-time. Also, I looked at some of the code
> generated by GNAT, and saw references to a secondary_stack_allocate
> (or something like that) function. So the storage for S and O is
> allocated somewhere, but it's on the stack? Is this something like
> alloca?

The fact that GNAT allocates it in one place does not mean all compilers
will do it in the same place.  Is your question specifically "how does
GNAT do this ?" ?

Larry Kilgallen




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                         ` Hyman Rosen
@ 1999-06-08  0:00                                           ` Samuel Mize
  1999-06-08  0:00                                             ` Hyman Rosen
  0 siblings, 1 reply; 116+ messages in thread
From: Samuel Mize @ 1999-06-08  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> wrote:
> Matthew Heaney <matthew_heaney@acm.org> writes:
...
>>   declare
>>     O : T'Class := Func_Return_T_Tic_Class;
>>   begin
>> In neither case is heap required.
> 
> And despite that, you said before that the size of O is determined
> at run-time, not at compile-time. Also, I looked at some of the code
> generated by GNAT, and saw references to a secondary_stack_allocate
> (or something like that) function. So the storage for S and O is
> allocated somewhere, but it's on the stack? Is this something like
> alloca?

I infer from the name "Func_Return_T_Tic_Class" that this function
returns a value of T'Class.  It may be of type T, or of a type
derived from T.

O is allocated on stack, just like any other declare-block variable.
(A function/procedure local variable would be just the same.)

O will receive that value, and is of the specific type returned, for
the duration of the declare block.  Next time this block is executed,
if Func's return is a different type, O will be of that specific type.

O's size is determined at run-time, when it finds out exactly what
type of object it has to hold.

I should say, of course, that O is allocated on stack on typical
architectures, by typical compilers.  There is no concept of "stack"
and "heap" required by the language, although Ada IS designed to
give you control over heap usage on machines where that concept
makes sense (as opposed, IIRC and e.g., to Lisp machines).

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                       ` Matthew Heaney
@ 1999-06-08  0:00                                         ` Hyman Rosen
  1999-06-08  0:00                                           ` Samuel Mize
  0 siblings, 1 reply; 116+ messages in thread
From: Hyman Rosen @ 1999-06-08  0:00 UTC (permalink / raw)


Matthew Heaney <matthew_heaney@acm.org> writes:
> On 07 Jun 1999 15:26:52 -0400, Hyman Rosen <hymie@prolifics.com> wrote:
> However, the declaration
>   declare
>     S : String := Func_Return_String;
>   begin
> is perfectly legal, and so is the declaration
>   declare
>     O : T'Class := Func_Return_T_Tic_Class;
>   begin
> In neither case is heap required.

And despite that, you said before that the size of O is determined
at run-time, not at compile-time. Also, I looked at some of the code
generated by GNAT, and saw references to a secondary_stack_allocate
(or something like that) function. So the storage for S and O is
allocated somewhere, but it's on the stack? Is this something like
alloca?




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                             ` Larry Kilgallen
@ 1999-06-08  0:00                               ` Hyman Rosen
  1999-06-08  0:00                                 ` Tucker Taft
                                                   ` (2 more replies)
  0 siblings, 3 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-06-08  0:00 UTC (permalink / raw)


kilgallen@eisner.decus.org (Larry Kilgallen) writes:
> The fact that GNAT allocates it in one place does not mean all compilers
> will do it in the same place.  Is your question specifically "how does
> GNAT do this ?" ?

I am trying to understand the mechanism behind T'Class. I have been told
that the size of such variables is determined at run-time, and also that
the heap is not required for such variables.

So, to anyone, if you don't mind taking the time to explain, how does
<compiler of your choice> implement this?

Also, I stated in an earlier message that I thought not allowing T'Class
variables in records was not orthogonal, but understandable in light of
the above. Now, suppose I need a function that returns a pair of values,
one of which is a T'Class and the other a boolean. Is there a way to do
this? I can't return a record containing the pair, because I can't have
such a record. I assume that a procedure with a pair of out parameters
won't work, because the T'Class variable which receives the output must
be initialized when declared, and then its tag can't change. So, is there
a way?




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                           ` Samuel Mize
@ 1999-06-08  0:00                                             ` Hyman Rosen
  0 siblings, 0 replies; 116+ messages in thread
From: Hyman Rosen @ 1999-06-08  0:00 UTC (permalink / raw)


Samuel Mize <smize@imagin.net> writes:
> I should say, of course, that O is allocated on stack on typical
> architectures, by typical compilers.

Yes, of course. I am trying to understand the mechanism behind T'Class
variables on ordinary architectures.

> O is allocated on stack, just like any other declare-block variable.
> (A function/procedure local variable would be just the same.)
> O's size is determined at run-time, when it finds out exactly what
> type of object it has to hold.

So where does the returned value from the function live between the
time the function returns and the time space is allocated on the stack
for O?




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                             ` Larry Kilgallen
@ 1999-06-08  0:00                               ` Hyman Rosen
  1999-06-14  0:00                                 ` Robert A Duff
  0 siblings, 1 reply; 116+ messages in thread
From: Hyman Rosen @ 1999-06-08  0:00 UTC (permalink / raw)


kilgallen@eisner.decus.org (Larry Kilgallen) writes:
> At a more basic level, storing a variable length structure on the stack
> requires that the machine code alter the amount of stack consumed on
> one call from the next.  Many other languages do not have programmer-
> visible constructs that do such a run-time determination, so perhaps
> that is what makes the concept seem strange.

They also don't have functions which return variable-length objects.
Where does the function return value live between the time the
function returns and the time that space is allocated for the variable
on the stack, using the size information in the return value?




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

* Re: Ada OO Mechanism
       [not found]                                   ` < <375E92CB.27850620@averstar.com>
@ 1999-06-09  0:00                                     ` Brian Rogoff
  1999-06-14  0:00                                       ` Robert A Duff
  0 siblings, 1 reply; 116+ messages in thread
From: Brian Rogoff @ 1999-06-09  0:00 UTC (permalink / raw)


On Wed, 9 Jun 1999, Tucker Taft wrote:

> Brian Rogoff wrote:
> > ...
> > This kind of problem is solved in some languages, like Common Lisp and
> > Dylan, with multiple value return and others, like ML and Haskell, with
> > tuples. Was the prospect of such a mechanism for Ada considered (yes I'm
> > sure :-) and if so why was it rejected? Seeing as Ada has aggregates, it
> > seems to me that multiple value return would also have been a feature.
> 
> In Ada, multiple value return is not significantly different
> from returning a record.  However, the problem we are trying
> to solve is not multiple value return, but rather returning
> objects of size unknown at compile-time without using the heap.

Yes, I know. I can understand why it makes sense that a record cannot 
contain unconstrained types, but I don't understand why a suitable 
generalization of Ada's ability to return unconstrained types could not be 
made to solve the problem being discussed *without* forcing a heap based
mechanism on Ada. An example might be returning two strings on the stack.

> Common Lisp, Dylan, ML, and Haskell all rely heavily on heap-based
> mechanism, and what is passed around are references (or tuples
> of references).

It was an unfortunate choice of example languages, but I think you'll
agree that the reliance on the heap is mostly an implementation issue, at
least in the case of ML (*). Sorry for the confusion, I just don't know of
any system programming languages with multiple value return. 

Incidentally, I'm not suggesting that this would be a good idea for Ada, I 
am just interested in whether it was discussed and if so what were the
reasons for not doing it. I can think of a few myself...

>  References, and records or arrays of references,
> are no problem in Ada either.  The challenge is to avoid the heap,
> and I believe Ada goes further than almost any language in accomplishing
> that. But as pointed out, there are some limitations, which result
> in the heap being necessary when things get too complicated.

Agreed. 

> > Using access params here to simulate functions with out params looks really
> > ugly to me.
> 
> Access parameters are the Ada 95 way to give functions "out" parameters.
> It has the advantage of making the OUT parameters quite visible, thanks
> to the use of 'Access at the call point.  Note that many languages don't
> support OUT parameters at all.  All they support is passing references.

Sure, in C I don't mind doing this, but when I write Ada my "Ada mindset" 
is such that this seems like a "workaround". If it really was a good idea 
to make out parameters visible then I'd imagine I should always use
'Access since (as Robert Dewar likes to point out) we should favor the 
reader and maintenance programer over the writer. That doesn't mean that 
I won't often do this, just that unless I had a very good reason for
avoiding heap access I'd use one of the other workarounds. 

-- Brian

(*) There are ML compilers which don't use garbage collectors, relying on
a technique called region inference which (roughly speaking) use a  
mark-release style allocator with mark and release points inferred
automatically. 

Its also true that Ada's avoidance of the heap is also implementation
dependent. Ada=>JVM compilers probably hit the heap quite a bit :-).







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

* Re: Ada OO Mechanism
  1999-06-08  0:00                               ` Hyman Rosen
  1999-06-08  0:00                                 ` Tucker Taft
@ 1999-06-09  0:00                                 ` Matthew Heaney
  1999-06-09  0:00                                 ` Samuel Mize
  2 siblings, 0 replies; 116+ messages in thread
From: Matthew Heaney @ 1999-06-09  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:

> Also, I stated in an earlier message that I thought not allowing T'Class
> variables in records was not orthogonal, but understandable in light of
> the above. Now, suppose I need a function that returns a pair of values,
> one of which is a T'Class and the other a boolean. Is there a way to do
> this? 

Not really, no.  Here are some ideas:

1) return a record containing a class-wide component allocated on the
   heap

  type RT is
    record
      O : T_Class_Access;  
      B : Boolean;
    end record;

  function Func_Ret_RT return RT;


2) Break in the function apart into two functions:

  function Func_Ret_T_Tic_Class return T'Class;

  function Func_Ret_Boolean return Boolean;

This doesn't preserve atomicity, however.  (But that's not always an
issue anyway.)


3) Embed the Boolean value in state of the object:

  function Func_Ret_T_Tic_Class return T'Class;

  function Func_Ret_Boolean (O : T) return Boolean;


> I can't return a record containing the pair, because I can't have
> such a record. 

That is correct.  Although, if you follow approach 1), you can put the
class-wide value on the heap.


> I assume that a procedure with a pair of out parameters won't work,
> because the T'Class variable which receives the output must be
> initialized when declared, and then its tag can't change.

Yes, that is correct.


> So, is there a way?

See the three bullets above.





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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                 ` Tucker Taft
  1999-06-08  0:00                                   ` Brian Rogoff
@ 1999-06-09  0:00                                   ` Robert Dewar
       [not found]                                   ` < <375E92CB.27850620@averstar.com>
  1999-06-09  0:00                                   ` Tucker Taft
  3 siblings, 0 replies; 116+ messages in thread
From: Robert Dewar @ 1999-06-09  0:00 UTC (permalink / raw)


In article <375D9A3D.E1CCCC63@averstar.com>,
  Tucker Taft <stt@averstar.com> wrote:
> For functions that return objects of size unknown to the
caller, the
> function creates the object on (or copies the object to) the
secondary
> stack, and then returns from the function *without* releasing
the
> secondary stack.  The caller takes care of releasing the
secondary stack
> once they are through with using the returned object.
>
> There are other compilers that use "local" heaps, or other
heap-based
> mechanisms.  They all still typically use some kind of
mark/release,
> though it may be a mark/release on a linked-list of objects,
rather
> than on a secondary stack.

By far the most efficient method of handling variable length
returned values is to return with the stack pointer depressed
so that the newly created value is still available. However
this cannot be done without wandering a bit outside the standard
ABI, and is thus infeasible in GNAT, which always uses the
standard ABI calling sequence.

Actually there is one routine alloca, which works the same way,
and indeed alloca has to be built in on many compilers,
precisely because it does not fit the standard ABI calling
sequence.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Ada OO Mechanism
       [not found]                           ` <t7zp2sr6yf.fsf@calumny.jyacc.c <375d9a3d.e1cccc63@averstar.com>
@ 1999-06-09  0:00                             ` Larry Kilgallen
  1999-06-09  0:00                               ` Tucker Taft
  0 siblings, 1 reply; 116+ messages in thread
From: Larry Kilgallen @ 1999-06-09  0:00 UTC (permalink / raw)


Reply-To: Kilgallen@eisner.decus.org.nospam
Organization: LJK Software
Lines: 14

In article <375D9A3D.E1CCCC63@averstar.com>, Tucker Taft <stt@averstar.com> writes:

> Several compilers use what is called a "secondary stack" (or a "data stack"),
> as distinct from the "primary stack" (or "control stack").
> The secondary stack is generally managed in a mark/release manner.
> There is one per task.

So in such compilers, how does specification of task (stack) size
relate to the primary and/or secondary stack ?

Do any compilers that use this method also support unlimited (well,
at least unspecified) stack size for the main task ?  For both stacks ?

Larry Kilgallen




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                               ` Hyman Rosen
  1999-06-08  0:00                                 ` Tucker Taft
  1999-06-09  0:00                                 ` Matthew Heaney
@ 1999-06-09  0:00                                 ` Samuel Mize
  2 siblings, 0 replies; 116+ messages in thread
From: Samuel Mize @ 1999-06-09  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> wrote:
> I am trying to understand the mechanism behind T'Class. I have been told
> that the size of such variables is determined at run-time, and also that
> the heap is not required for such variables.

This specific question has been beat to death, but I wanted to point out
a generality.

When folks say that an Ada feature doesn't use the heap, they usually
mean that it doesn't require the programmer to explicitly use the heap.
The run-time has to create and delete scratch areas from time to time,
and it's not defined where these are.

Best,
Sam Mize

-- 
Samuel Mize -- smize@imagin.net (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                                 ` Tucker Taft
                                                     ` (2 preceding siblings ...)
       [not found]                                   ` < <375E92CB.27850620@averstar.com>
@ 1999-06-09  0:00                                   ` Tucker Taft
  3 siblings, 0 replies; 116+ messages in thread
From: Tucker Taft @ 1999-06-09  0:00 UTC (permalink / raw)


Brian Rogoff wrote:
> ...
> This kind of problem is solved in some languages, like Common Lisp and
> Dylan, with multiple value return and others, like ML and Haskell, with
> tuples. Was the prospect of such a mechanism for Ada considered (yes I'm
> sure :-) and if so why was it rejected? Seeing as Ada has aggregates, it
> seems to me that multiple value return would also have been a feature.

In Ada, multiple value return is not significantly different
from returning a record.  However, the problem we are trying
to solve is not multiple value return, but rather returning
objects of size unknown at compile-time without using the heap.
Common Lisp, Dylan, ML, and Haskell all rely heavily on heap-based
mechanism, and what is passed around are references (or tuples
of references).  References, and records or arrays of references,
are no problem in Ada either.  The challenge is to avoid the heap,
and I believe Ada goes further than almost any language in accomplishing
that.  But as pointed out, there are some limitations, which result
in the heap being necessary when things get too complicated.

> Using access params here to simulate functions with out params looks really
> ugly to me.

Access parameters are the Ada 95 way to give functions "out" parameters.
It has the advantage of making the OUT parameters quite visible, thanks
to the use of 'Access at the call point.  Note that many languages don't
support OUT parameters at all.  All they support is passing references.

> -- Brian

-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




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

* Re: Ada OO Mechanism
  1999-06-09  0:00                             ` Larry Kilgallen
@ 1999-06-09  0:00                               ` Tucker Taft
  0 siblings, 0 replies; 116+ messages in thread
From: Tucker Taft @ 1999-06-09  0:00 UTC (permalink / raw)


Larry Kilgallen wrote:
> 
> Reply-To: Kilgallen@eisner.decus.org.nospam
> Organization: LJK Software
> Lines: 14
> 
> In article <375D9A3D.E1CCCC63@averstar.com>, Tucker Taft <stt@averstar.com> writes:
> 
> > Several compilers use what is called a "secondary stack" (or a "data stack"),
> > as distinct from the "primary stack" (or "control stack").
> > The secondary stack is generally managed in a mark/release manner.
> > There is one per task.
> 
> So in such compilers, how does specification of task (stack) size
> relate to the primary and/or secondary stack ?

It varies.  In some, it is the sum of the space given to the
primary and secondary stack, which "grow" toward each other.
In others, it only controls the primary stack, and the secondary
stack is represented as an arbitrarily extendable linked-list of
large chunks.  There are probably other combinations as well.

> Do any compilers that use this method also support unlimited (well,
> at least unspecified) stack size for the main task ?  For both stacks ?

I would guess that many compilers that run on Unix-like timesharing
systems use the automatic stack extension feature to handle the
main primary stack, and either have a fixed size for the secondary
stack, or represent the secondary stack using chunks and have no
fixed limit.  On most embedded systems, I suspect that the main
task's primary and secondary stack sizes are set at link-time.

> Larry Kilgallen

-- 
-Tucker Taft   stt@averstar.com   http://www.averstar.com/~stt/
Technical Director, Distributed IT Solutions  (www.averstar.com/tools)
AverStar (formerly Intermetrics, Inc.)   Burlington, MA  USA




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

* Re: Ada OO Mechanism
  1999-06-09  0:00                                     ` Brian Rogoff
@ 1999-06-14  0:00                                       ` Robert A Duff
  0 siblings, 0 replies; 116+ messages in thread
From: Robert A Duff @ 1999-06-14  0:00 UTC (permalink / raw)


Brian Rogoff <bpr@shell5.ba.best.com> writes:

> Yes, I know. I can understand why it makes sense that a record cannot 
> contain unconstrained types, but I don't understand why a suitable 
> generalization of Ada's ability to return unconstrained types could not be 
> made to solve the problem being discussed *without* forcing a heap based
> mechanism on Ada. An example might be returning two strings on the stack.

Well, you can return two strings on the stack by returning a record that
looks like this:

    type String_Pair(Length1, Length2: natural) is
        record
            String1: String(1..Length1);
            String2: String(1..Length2);
        end record;

But you can't do that with class-wide, because there's no constraint to
constrain the tag of an object, analogous to the constraints on the
upper bounds of the above strings.  Adding such a concept to the
language would add functionality, but would also add complexity.
Probably not worth it.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Ada OO Mechanism
  1999-06-08  0:00                               ` Hyman Rosen
@ 1999-06-14  0:00                                 ` Robert A Duff
  0 siblings, 0 replies; 116+ messages in thread
From: Robert A Duff @ 1999-06-14  0:00 UTC (permalink / raw)


Hyman Rosen <hymie@prolifics.com> writes:

> kilgallen@eisner.decus.org (Larry Kilgallen) writes:
> > At a more basic level, storing a variable length structure on the stack
> > requires that the machine code alter the amount of stack consumed on
> > one call from the next.  Many other languages do not have programmer-
> > visible constructs that do such a run-time determination, so perhaps
> > that is what makes the concept seem strange.
> 
> They also don't have functions which return variable-length objects.
> Where does the function return value live between the time the
> function returns and the time that space is allocated for the variable
> on the stack, using the size information in the return value?

One model is to just leave it on the stack.  The function return then
jumps back to where it came from, but does *not* chop back the stack.
At the call site, the caller then copies the function result to wherever
it belongs.  Or, if the call site is another return statement, it just
leaves it where it is, and lets the caller's caller deal with it.

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

end of thread, other threads:[~1999-06-14  0:00 UTC | newest]

Thread overview: 116+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-05-20  0:00 Ada OO Mechanism Shawn M. Root
1999-05-20  0:00 ` Samuel Mize
1999-05-20  0:00   ` David Botton
1999-05-20  0:00     ` Samuel Mize
1999-05-20  0:00       ` David Botton
1999-05-24  0:00   ` Hyman Rosen
1999-05-24  0:00     ` Robert Dewar
1999-05-24  0:00       ` Hyman Rosen
1999-05-24  0:00         ` David Starner
1999-05-24  0:00           ` bob
1999-05-24  0:00             ` David Starner
1999-05-25  0:00               ` Ole-Hjalmar Kristensen
1999-05-25  0:00                 ` Florian Weimer
1999-05-25  0:00                 ` Mark A Biggar
1999-05-25  0:00                   ` Hyman Rosen
1999-05-25  0:00                     ` Richard D Riehle
1999-05-25  0:00                       ` David Botton
1999-05-26  0:00                         ` Tom Moran
1999-05-27  0:00                       ` Aidan Skinner
1999-05-25  0:00                     ` Samuel Mize
1999-05-25  0:00                       ` Hyman Rosen
1999-05-25  0:00                         ` Samuel Mize
1999-05-25  0:00                           ` Chris
1999-05-25  0:00                             ` David Botton
1999-05-27  0:00                               ` Aidan Skinner
1999-05-27  0:00                                 ` Gautier
1999-05-27  0:00                             ` Samuel Mize
1999-05-25  0:00                         ` Brian Rogoff
1999-05-25  0:00                           ` Jim
1999-05-26  0:00                           ` Robert Dewar
1999-05-26  0:00                             ` Brian Rogoff
1999-05-25  0:00                         ` Richard D Riehle
1999-05-25  0:00                           ` Hyman Rosen
1999-05-26  0:00                             ` Ray Blaak
1999-05-26  0:00                               ` Hyman Rosen
1999-05-26  0:00                               ` Richard D Riehle
1999-05-26  0:00                                 ` Hyman Rosen
1999-05-27  0:00                                   ` Richard D Riehle
1999-06-05  0:00                                     ` Matthew Heaney
1999-06-07  0:00                                       ` Hyman Rosen
1999-05-28  0:00                                   ` Laurent Guerby
1999-06-05  0:00                                   ` Matthew Heaney
1999-06-07  0:00                                     ` Hyman Rosen
1999-06-08  0:00                                       ` Robert Dewar
1999-06-08  0:00                                         ` Markus Kuhn
1999-06-08  0:00                                           ` Stanley R. Allen
1999-06-08  0:00                                         ` Stanley R. Allen
1999-06-08  0:00                                       ` Matthew Heaney
1999-06-08  0:00                                         ` Hyman Rosen
1999-06-08  0:00                                           ` Samuel Mize
1999-06-08  0:00                                             ` Hyman Rosen
     [not found]                           ` <t7zp2sr6yf.fsf@calumny.jyacc.c <t7emjmmx8w.fsf@calumny.jyacc.com>
1999-06-08  0:00                             ` Larry Kilgallen
1999-06-08  0:00                               ` Hyman Rosen
1999-06-08  0:00                                 ` Tucker Taft
1999-06-08  0:00                                   ` Brian Rogoff
1999-06-09  0:00                                   ` Robert Dewar
     [not found]                                   ` < <375E92CB.27850620@averstar.com>
1999-06-09  0:00                                     ` Brian Rogoff
1999-06-14  0:00                                       ` Robert A Duff
1999-06-09  0:00                                   ` Tucker Taft
1999-06-09  0:00                                 ` Matthew Heaney
1999-06-09  0:00                                 ` Samuel Mize
     [not found]                           ` <t7zp2sr6yf.fsf@calumny.jyacc.c <t7r9nmz8ou.fsf@calumny.jyacc.com>
1999-06-08  0:00                             ` Larry Kilgallen
1999-06-08  0:00                               ` Hyman Rosen
1999-06-14  0:00                                 ` Robert A Duff
     [not found]                           ` <t7zp2sr6yf.fsf@calumny.jyacc.c <375d9a3d.e1cccc63@averstar.com>
1999-06-09  0:00                             ` Larry Kilgallen
1999-06-09  0:00                               ` Tucker Taft
1999-05-27  0:00                         ` Samuel Mize
1999-05-27  0:00                           ` Hyman Rosen
1999-05-28  0:00                             ` Samuel Mize
1999-05-28  0:00                             ` Laurent Guerby
1999-05-28  0:00                               ` Richard D Riehle
1999-05-28  0:00                                 ` Tom Moran
1999-05-27  0:00                         ` Samuel Mize
1999-05-27  0:00                           ` Jon S Anthony
1999-05-28  0:00                     ` Robert I. Eachus
1999-05-28  0:00                       ` Brian Rogoff
1999-05-29  0:00                       ` Ehud Lamm
1999-05-30  0:00                         ` chris
1999-05-30  0:00                           ` Robert Dewar
1999-05-30  0:00                           ` Harry George
1999-05-30  0:00                             ` Vladimir Olensky
1999-05-31  0:00                               ` Robert Dewar
1999-05-31  0:00                           ` Vladimir Olensky
1999-06-03  0:00                             ` Dale Stanbrough
1999-06-02  0:00                               ` mike
1999-06-03  0:00                                 ` Robert Dewar
1999-06-06  0:00                                   ` David Botton
1999-06-07  0:00                                     ` Robert Dewar
1999-06-01  0:00                           ` Richard D Riehle
1999-06-03  0:00                         ` Matthew Heaney
1999-06-03  0:00                     ` Matthew Heaney
1999-05-24  0:00         ` Mike
1999-05-25  0:00           ` Robert Dewar
1999-05-25  0:00     ` Samuel Mize
1999-05-25  0:00       ` Hyman Rosen
1999-05-25  0:00         ` David Starner
1999-05-26  0:00         ` Ole-Hjalmar Kristensen
1999-05-26  0:00         ` Laurent Guerby
1999-05-26  0:00           ` Hyman Rosen
1999-05-28  0:00             ` Laurent Guerby
1999-06-01  0:00               ` Hyman Rosen
1999-06-03  0:00                 ` Fraser Wilson
1999-06-03  0:00     ` Matthew Heaney
1999-06-03  0:00       ` Hyman Rosen
1999-05-21  0:00 ` Dale Stanbrough
1999-05-20  0:00   ` bob
1999-05-21  0:00     ` Dale Stanbrough
1999-05-21  0:00   ` Richard D Riehle
1999-05-21  0:00     ` Marin David Condic
1999-05-21  0:00       ` Dan Nagle
1999-05-24  0:00         ` Marin David Condic
1999-05-21  0:00       ` Steve
1999-05-21  0:00     ` Shawn M. Root
1999-05-21  0:00       ` Richard D Riehle
1999-05-25  0:00         ` Shawn M. Root
1999-05-25  0:00   ` Don Overheu

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