Ok Ok, I've watched this thread long enough to respond...
Here's a history lesson...
Classic-Ada was a preprocessor to Ada 83 that had the features your
describing/wanting.
(Other two options at that time were Dragoon and uh oh - can't remember the name
- oh well.)
We were the first. Might as well brag about it...
The preprocessor took Ada83+the 9 extra reserved words and generated Ada. I used
to run the ACVC on it to test its ability to handle Ada. Of course it didn't
pass everything - one of our reserved words is tested for in the ACVC. But the
stuff that counted it passed.
With 9 extra reserved words we added the object-oriented paradigm to Ada.
Features included:
Class and Instance objects,
Inheritance of both class and instance methods,
Inheritance of instance variables,
Polymorphism,
Dynamic Binding of messages to objects (instance or class),
and after a year or two - Real, Transparent, object persistence.
It didn't sell very well. People would rather whine about EXTENDING the Ada
language - a big no no. Also, dynamic binding was 1..6 times a standard
procedure call. We did a lot of optimizing here so in many cases it was no more
expensive than 1..2 procedure calls. Our opinion was that if you used a case
statement to implement selecting an action to take based upon some switch, then
you were doing by hand what we did automatically. So in reality, the hit was a
non-issue.
Initially our 9 extra reserved words to Ada were:
class, superclass, instance, method,
send, self, super, instantiate, destroy.
Later we added a 10th - persistent. With it you could define a truly persistent
class - without ANY EXTRA CODE! Instance objects were automatically stored/saved
on disk and your oo-application never new!
The persistence was modeled over our own filebase, but we did a job for Raytheon
where we quickly inserted their database solution to our persistence. Piece of
cake.
Most of my years of Ada experience was using both Classic-Ada and Ada83. I
started out with both object-oriented and Ada experience. It was a wonderfully
simple paradigm. I view it as heads and tails simpler than tagged types - tho'
not nearly as flexible/powerful.
Steve Nies invented it. I ported it to various platforms and did the Raytheon
mod as well as some of the reporting features. And a few others in our company,
who I'll not name, did modifications/improvements.
It was written in Ada - no not Classic-Ada. Who's dumb enough to bootstrap a
compiler!
Anyway, since we generated Ada code - without name-mangling (remember, you're
debugging OUR generated code), Classic-Ada code could be compiled on ANY Ada
compiler. I compared our model to C++ (which I didn't know) and Ada9x and one
other language (Smalltalk or CLOS - which I knew) for my Master's Thesis under
Chuck Engle. I've always liked Classic-Ada's model better than Ada's. In fact
our company proposed it as a solution to Ada9x. However, or eventually... the
Ada95 model grew on me and I've come to realize that it is an Ada-Solution to
the problem of adding OO to Ada. Sometimes cumbersome, sometimes elegant, always
consistent. And consistency is what caught my attention about the language in
the first place.
Now, as to modifying it for Ada 95... well, it could be done with some effort.
I'll save this for another message if anyone wants me to elaborate on how we did
what we did.
I've placed some actual code below...
Regards,
joe
-- ====== A312 1116 47FC 79EA : 7AA6 592C ECDC F109 ====== --
Joe Tallet Senior Software Architect
Harris W3-7759 [log in to unmask]
150 S. Wickham Rd. (v) 407.984.6376
Melbourne, FL 32904 (fax)407.984.5770
-- ==== To be, and not to be. That is the eigenstate. ==== --
And of course the bootstrap comment (above) was an Obvious joke. And of course
this sentence just made fools of those who started to comment on it. I just
couldn't resist. ;-)
Here is an example of how you would code a class (off the top of my head and
after 4 years but it should process and compile anyway). I've Uppercased the
Classic-Ada reserved words for you.
-- Class spec. - just like an Ada package spec.
-- Sure, you could with other packages/classes.
with Vehicle;
-- But, you don't have to do this to make the superclass
-- call (see below). Since this code makes use of the
-- type Range_Type which is defined in Vehicle, it
-- behaves like Ada - you need to get visibility to it.
CLASS Airplane is
-- straightforward here... we convert class to package for
-- the Ada compiler!
SUPERCLASS Vehicle; -- only single inheritance allowed.
METHOD Create (anObject : out Object_Id);
-- This is a real class method. Completely inheritable (although
-- you'd never want to use an inherited class method for
-- instance creation.
-- Object_Id is a "reserved type" used by Classic-Ada.
INSTANCE METHOD Initialize;
INSTANCE METHOD Initialize (aRange : in Vehicle.Range_Type);
-- These are instance methods - note overloading. They are
-- inherited by children of Airplane.
-- Note that we can qualify Range_Type. It is a type defined
-- within the class Vehicle.
INSTANCE METHOD Finalize;
end Airplane;
-- Class body.
CLASS body Airplane is
Current_Range : INSTANCE Vehicle.Range_Type;
-- Note that the instance variables are declared within
-- the class body. This promotes information hiding and
-- encapsulation at the spec level.
-- Also note that these variables are inherited by
-- children of Airplane - true to the OO paradigme.
METHOD Create (anObject : out Object_Id) is
aPlane : Object_Id := INSTANTIATE;
-- The reserved word instantiate creates an
-- instance of the class.
begin
-- If you want to initialize the newly created object...
-- just send it a message.
SEND (aPlane, Initialize);
anObject := aPlane;
end Create;
INSTANCE METHOD Initialize is
begin
Current_Range := 0;
-- No visibility problem here - inherited or not.
SEND (SUPER, Initialize);
-- This is a message invocation. The message Initialize
-- is sent to the superclass of Airplane.
end Initialize;
INSTANCE METHOD Initialize (aRange : in Vehicle.Range_Type) is
begin
SEND (SUPER, Initialize);
-- You can also send to yourself...
-- This is also an example of a send with parameters.
SEND (SELF, Set_Range, New_Range => aRange);
end Initialize;
INSTANCE METHOD Finalize is
begin
SEND (SUPER, Finalize);
DESTROY;
-- The destroy keyword deallocates the object.
-- Do your instance variable cleanup first (of course).
end Finalize;
end Airplane;
-----Original Message-----
From: Samuel Mize [SMTP:[log in to unmask]]
Sent: Friday, November 20, 1998 9:19 PM
To: [log in to unmask]
Subject: "class" pragma suggestion
Robert I. Eachus wrote:
>
> At 06:16 AM 11/17/98 GMT, Simon Wright wrote:
> > From: Samuel Mize <[log in to unmask]>
> > Perhaps a "class" package would also require that all the
subprograms
> > in the package have the controlling operand as the first parameter
> > (the return value, for functions). This would help out the people
who
> > find the syntax "object.message" to be more readable.
>
> This is starting to get silly.
Sorry, I thought this list was (among other things) a place to toss
out and develop ideas that might help make Ada more saleable to others.
> function Message (Text: in Clever_Ideas) return Better_Ideas is...
The name of the function is "team-ada" and I was calling it.
- - - - -
>Ada is a very rich language, and while I
> can understand having a tool to detect some departures from local
coding
> standards and software engineering practices, putting on a
straight-jacket
> is not all that good an idea.
I don't see why marking some packages, and putting limits on those
marked packages, would be "putting on a straight-jacket." If a
given package needs to exceed those limits, you don't use the
marker, just as you don't use "positive" for counting from zero.
But I was just tossing out a thought about "class" packages. If
you're saying I defined too tight a limit on parameter lists, I'd
like to understand what you mean. Someone else (I think it was Simon)
pointed out that we need selector functions.
Did you perhaps think I was saying that all packages should be
classes? Good grief, no.
Perhaps a "class" pragma would have a parameter that states whether
the package's parameter lists are limited to object-first order.
Perhaps the pragma's parameters would let you specify several types
of object-oriented coding limits -- another advantage of marking
packages as "classes" with a pragma.
To some extent I was reacting to the typical comment that you can
do classes in Ada, it's just a tagged type in a package. No. That
isn't a language-defined class. There are semantic constraints
behind the concept "class" that are not checked by putting a tagged
type in a package.
If you do a tagged-type-in-a-package combo right, you wind up with
something equivalent to a class.
But if you do integer codes right, you wind up with something
equivalent to an enumeration. Guess we don't need those. If you
do assembly coding right, you wind up with something equivalent to
a tasking run-time.
In all these cases, I'd rather the compiler was helping me check my
code, and your code, and especially the code we have to use from that
guy over there who thinks C is just too kewl.
I think it's interesting and exciting that such methodology checking
could be integrated into an Ada compilation system with pragmas, if
we want to, without some kludgy thing like a pre-processor.
You could use a pre-processor or stand-alone tool too, of course. But
it would have to do some semantic analysis -- may as well use the
compiler if you can.
I don't know much about ASIS -- might it allow class-checking to be
integrated into a tool suite WITHOUT being integrated into a specific
compiler? Kewl, d00d!
- - - - -
> For example:
>
> type Set is...
>
> function "+"(L,R: Set) return Set;
> function "-"(L: Set, R: Element) return Set;
> -- and so on.
Can you explain what you are trying to communicate with your example?
I don't understand your point.
- - - - -
> In addition if you really prefer the class.method(parameters)
notation,
Nobody wants that. Some people want object.method(parameters) .
> Ada has it all over the place:
> Protected_Object.Method(Parameters);
> Task.Entry(Parameters);
> Type'Attribute_Function(Parameters)
> and of course, and most important:
> Package.Operation(Parameters);
Yep, lots of places except for tagged types, which is how Ada
implements object-oriented programming, which is the context in
which people are carping about not having it.
>[explains how to get object.method notation with generic packages]
> Generic instance as object is not a good model if you
> have many objects of the class, or if the number of objects is highly
> dynamic. But it is great when you have objects with no particular
> hierarchy, and many different types of state variables.
So as long as you don't want to define a class hierarchy, or do
programming by extension, or have polymorphism, and you have a
very limited number of instances, you can use that technique. I
don't think you'll win a lot of converts from C++ or Smalltalk
with that sales pitch.
I'm not arguing for or against object.method notation. Some people
think it's important for clarity, a desideratum I would think we can
all respect. I was trying to think up something that might help
such people transition to Ada.
"Look," we could say, "you can require that a particular tagged
type's operations start their parameter list with the controlling
object. It makes the receiving object just as obvious as
object.method notation does. But if you're just doing programming
by extension, not object-oriented programming, you don't have to
live with that limit."
By the way, perhaps such a "class" package's type should only be
extensible through other, similarly-limited "class" packages, to
ensure that all its operations follow the parameter-ordering rule.
Best,
Sam Mize
--
Samuel Mize -- [log in to unmask] (home email) -- Team Ada
Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam
|