comp.lang.ada
 help / color / mirror / Atom feed
From: "Ekkehard Morgenstern" <ekkehard.morgenstern@onlinehome.de>
Subject: Re: Question about OO programming in Ada
Date: Thu, 27 Nov 2003 03:10:28 +0100
Date: 2003-11-27T03:10:28+01:00	[thread overview]
Message-ID: <bq3mef$49e$1@online.de> (raw)
In-Reply-To: GpednY19wYJAdFmiRVn-gg@comcast.com

First of all, thank you very much for that elaborate reply! :-)
I had to print it out and read it twice to understand it, but it was very
much worth it! :-)

Today I rewrote all my packages to be generic and not use a single access
type! Of course, I had to do away with linked lists. Instead I defined a
parameterized Vector (array) class. Not only has the source become
thrillingly short, but also very easy to handle and inherit from. :-)

This will be sufficient as a foundation to build upon, until I receive the
book "Programming in Ada 95" that I ordered a couple of days ago. :-)

I will try to follow the advice you've given and hide the use of access
types, if I really them, inside the private part of the packages affected.

But I have a few more questions, so it'd be great if you could answer them.
:-)

"Robert I. Eachus" <rieachus@comcast.net> schrieb im Newsbeitrag
news:GpednY19wYJAdFmiRVn-gg@comcast.com...
> That is complex enough to deserve an example.

Thanks for the example, it gave me a good insight into the matter. :-)

> abstract function Register(Owner: in out Person'Class;
>                             The_Vehicle: in out Vehicle)
>                      return Registration'Class;
>
> Perhaps when you finish, you will end up returning a Registration_Ref,
> but so far it isn't necessary to make that type public.  (Notice that
> you can always write Register(Someone, Car)'Access, if you really need
> to get an access value to assign to a Registration_Ref, or in some cases
> Register(Someone, Car)'Unchecked_Access.)

Thanks. That's good to know. What does "Unchecked_Access" do?

> Later you will write (child) packages to deal with cars, trucks, buses,

Why child packages? Does the package hierarchy matter for derived classes?

> ride motorcycles.  This can be determined by nested dispatching, or more
> usually by "if Owner in Motorcycle_Driver'Class then..."

This is really a great feature! So I can practically test if any object is a
member of a particular class, or set of classes?

I read in the OO part of the Rationale that a classwide type is actually
represented internally with a set of key/value pairs, right? What kinds of
other applications does that have?

> But the second instance, the use of a classwide result type is more
> interesting.  This is not to cause dispatching, but to actually return
> an object whose class is not known at compile time.  A typical usage is:
>
> procedure Something (...) is
>    The_Registration: Registration'Class
>               := Register(The_Owner, The_Vehicle);
> begin
>    -- further operations on The_Registration, which may involve
>    -- dispatching calls.
> end Something;

I still wonder if The_Registration is actually a reference, or is it the
object returned by Register()?

I.e. if I wanted only a reference to the object, would I have to use an
access to Registration'Class?

I wonder about this stuff because I'd like implement a linked list package,
which provides one set of subprograms for all types of derived linked lists
and list nodes.

Now, if I had a function like this:

    function Next( N : in out Node'Class ) return Node'Class;

(btw, is it ok to use "in out" in this case with a function?)

Can I return an object of type Node'Class, or do I have to return an access
to it?

And the Node implementation, can it look like this:

    type Node is tagged limited
    record
    Succ : Node'Class;
    Pred : Node'Class;
    end record;

I gather from previous discussions that Node'Class represents an actual
object, not a reference to it, so I'd have to use access types in this case,
which would give

    type Node_Ref is access Node'Class;

    type Node is tagged limited
    record
    Succ : Node_Ref;
    Pred : Node_Ref;
    end record;

Or do I err?

If I use the latter version, and keep the function Next() as defined above,
would the object be copied when it is returned? Or is that precluded by the
fact that it's a limited type?

But if I modify Next() to be something like

    function Next( N : Node_Ref ) return Node_Ref;

how can I avoid casting N and the return value from a derived class?

What's the optimal way in Ada to do this?

> > First of all, how do I accomplish returning a reference in Ada?
>
> Whether an object is passed by value, value-return, or reference depends
> on the object's class, not on whether the parameter is in, in out, or
> out.  In parameters can be referenced but not changed, in out parameters
> can be referenced and changed, and for out parameters the attributes are
> defined at the point of the call, but there may not be an initial value.

But what about return values from functions? Or does the return value in a
function correspond to an "out" parameter in a procedure?


> > i.e. the difference between
> >
> >     procedure Proc( Param : in out Type'Class );
> >
> > and
> >
> >     type Type_Class_Access is access Type'Class;
> >     procedure Proc( Param : in Type_Class_Access );
>
> Not much.  Or rather, using the second form unnecessarily is a sign that
> you are new to Ada.

Yes, I am, but I'm trying to get things right! :-)

> There are cases where the access parameter won't
> cause any additional difficulties, and other cases where it will mean
> that you need to explicitly free the storage to avoid memory leaks.

Yeah, I know that problem can be addressed by creating an instance of the
Unchecked_Deallocation procedure.

BTW, how do I use the Finalization package? I'd like to use things like
constructors and destructors sometimes to be able to initialize / cleanup
objects when they're created or destroyed.

> If you pass objects instead of pointers, you eliminate the potential
> memory leaks.

That's true and a grand feature of Ada because it does away with bookkeeping
on the programmer's part in general.

For now, I'm using arrays where possible instead of lists, which can be
parameterized in generic packages. Then I only need to create an instance of
that package for the application in question, and multiple instances if
necessary. :-)

I'm really surprised how short my source code has become. It's just the way
programming's meant to be that I can concentrate on the key tasks at hand.
:-)

Generic packages remind me a bit of C++ templates, but generics are much
more powerful. :-)

What I also find very useful is the renaming of packages / procedures etc.
Does that have any impact on dispatching or inheritance (in the case of
renaming procedures)?

BTW, can I instantiate a generic package in a procedure body (initialized
with a value passed as a parameter)? (I didn't try yet)


>  This doesn't mean you shouldn't use pointers (access
> types) where appropriate.  But in Ada a good rule is that you only use
> explicit access types to create data structures.  And since you normally
> use abstract data types to implement these structures, the notation is
> limited to the private parts and bodies of a few packages.

I will have to try that with my doubly-linked list problem. Does it really
change much if I use abstract Nodes and Lists in the example I gave above?

The problem with arrays is that they need to be preallocated to a particular
size, which can consume a lot of memory. Lists and Nodes occupy only the
memory that they actually use.

And which method is faster?


> (And you
> probably chose those packages from a library instead of "rolling your
> own.")

What kind of library would you recommend to me? I'd need some linked lists,
queues, containers and so on, but I'd like to have versions that are
completely generic.

I could write them myself, and I probably have to, because I need to limit
the amount of third-party software that I use.

I plan to use Ada for a major software project in which I might even have to
implement an Ada compiler for a virtual machine that I've designed myself,
and which I might also implement in Ada.

That's why it's very important to me to do my packages right, right from the
start, because I perhaps cannot change the design after building up on it.

> But sometimes you need to create your own interlinked data
> structures, as in the example of Persons, Vehicles, and Registrations.
> In those cases, you can use different data structure packages, written
> as generics to implement some of the data structures you need.

Indeed, generics seem to be a very powerful feature in Ada that can be used
in a lot of ways.

> Incidently, this is my problem with a set of data structure packages as
> a part of Ada.  There are several ways to implement these structures in
> Ada, and which one you want to use depends on intimate details of the
> problem you are trying to solve.  So a limited set of official solutions
> IMHO would be worse than the current situation.  (A core set of data
> structure packages in the standard, plus an indication that compiler
> vendors and others are encouraged to extend the set is a different story.)

That's ok. It isn't really all that much code to write such things like
lists, queues, stacks, etc., but of course it would be neat to have them in
the Ada package, because they're constructs frequently used.

> Don't cheat yourself.  It is possible to subset Ada's support for
> object-oriented programming to match what you currently know about the
> subject from C++ or some other OO languages.  But the Ada model is much,
> much richer than that.  A lot of this richness involves information
> hiding.

Yeah I agree. Like in any language, getting a grasp of the language features
might take some time, but it's worth it, of course! :-)


>  In Ada you constantly find yourself asking two questions:
>
>     What is the minimum required information to use this subprogram,
> data-type, abstraction, and so on?

Yeah, I already noticed this today when I rewrote my classes to use
generics. They're only a fraction of the code size they were before. :-)

>
> and:
>
>     Is there a different way to express this which allows more
> information hiding?
>
> Why this emphasis on information hiding?  The converse of information
> hiding is coupling.  The more coupling you have, the more bugs you have,
> the bugs are harder to find, and fixing bugs is more likely to create
> additional bugs.  So maximizing information hiding is the easy way to
> bug free programming.

Yeah, that's true, the more you encapsulate and abstractify classes and
packages as black boxes, the more universally useful they get. :-)

> Yes.  Ada is trying to tell you something.  In Ada the intent is that
> cleaner means better.  If you are converting back and forth all over the
> place, it means that your programming model is not well thought out.

How do I avoid casting access types between derived classes?

> Quicker is possible, but tough.  We used to say that learning Ada was 5%
> learning syntax and 95% learning software engineering.

It's true that learning Ada simple, especially for people who already know
other programming languages.

I can't believe how much I learned in only a couple of days.

Software design is not my problem, it's what I've been doing most of my
life, so it's a piece of cake now that I have Ada. :-)

(Ada can really save a LOT of typing! Just because it has such powerful
constructs. I don't mind at all typing away at packages and stuff knowing
I'd need 10 times the source with C++ or more even with C)

> Then along came
> Ada 95.  It cleaned up a lot of special cases to make learning how to
> program in Ada easier, and added support for several powerful new
> programming paradigms.  My guess is that Ada 95 made learning the
> language somewhat easier, but tripled the amount of software engineering
> you need to know to use the whole language.  You can see that above,
> with delegation of dispatching, multiple dispatch, and returning
> classwide objects.  Those are just from the object-oriented extensions
> in Ada 95.

Yes, but you don't really need to know about all these things to program in
Ada, and that's really a good thing. You can get along well with basic
constructs, and the more intricate details of the language can be postponed
to be used later when necessary.

> I could probably teach a one semester course on how to use child
> packages in Ada, and then follow it with a semester on generic package
> parameters in Ada, or a semester on real-time programming in Ada, or a
> semester on high integrity programming, oops make that at least two
> semesters!  I could also probably create a year long course on how to
> use access discriminants in Ada, but IMHO, maybe 30 people world-wide
> need to know all the tricks of using them.  (Maybe a course on when it
> looks like you need to use access discriminants, but don't?)

You can put me on that list for some later point in time. ;-)

I hope I can get back to you with my questions when I have to write an Ada
compiler and run-time system.

Perhaps my understanding of the language will be real good by then, but I
might still need detailed information about how things are supposed to be.

> >               English is a foreign language to me, and I'd rather not
> > read umpteen pages of Ada language theory when I can avoid it! ;-) )
>
> Hmmm.  There should be some good Ada reference material auf Deutch, but
> I don't know what offhand.  (And at this point I'm not going to go back
> and rewrite the above. ;-)

Yeah, that'd be a lot of work! ;-)

I haven't looked yet for some German-language Ada resources, but I don't
really need them right now. It's a shame, I found no Ada books in German for
beginners on Amazon. But I prefer reading the English language versions to
German translations anyway. :-)

> 100% Ada, no bugs--the only way to create software.

That sounds promising! :-)

I hope I'll be able to write all my future software, at least in my private
projects, in Ada. It has a lot of features I always wanted in a programming
language. And it's a great programming language concept anyway, mature and
tested! (I came up with similar designs on my own and found Ada by
curiousity, recalling a hint that someone gave to me over ten years ago.)
Ada is indeed the best programming language I've ever seen and it seems to
be relatively easy to write a compiler for (like, compared with C++),
because of the logical and well-defined structure. And it has many features
that I haven't found in any other language yet, like value range checking
and arbitrary numerical types, and parameterizable packages.

All of Ada's features are very promising for the development of
well-designed bug-free software. :-)
(because, you know, I'm not worried about myself there, because I can write
bug-free software in any programming language, but if I write a development
environment with its own language, I want to choose a language that enforces
or at least encourages bug-free programming for those less experienced than
people like me, also, and Ada seems to be the ideal choice! Even if I
support other languages -- if my VM is designed for Ada, and Ada is the
prime language for it, then all other languages can benefit from it as
well.)






  reply	other threads:[~2003-11-27  2:10 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-25 19:04 Question about OO programming in Ada Ekkehard Morgenstern
2003-11-25 20:17 ` Randy Brukardt
2003-11-26  0:34   ` Ekkehard Morgenstern
2003-11-26  6:17     ` Vinzent 'Gadget' Hoefler
2003-11-26  9:29     ` Dmitry A. Kazakov
2003-11-26 15:54     ` Stephen Leake
2003-11-26 20:07       ` Randy Brukardt
2003-11-26 21:36         ` Stephen Leake
2003-11-26  8:56   ` Peter Hermann
2003-11-25 20:55 ` Martin Krischik
2003-11-26  0:22   ` Ekkehard Morgenstern
2003-11-26  1:00     ` Jeffrey Carter
2003-11-26 16:36     ` Martin Krischik
2003-11-26 18:09       ` Robert I. Eachus
2003-11-27 13:45         ` Jean-Pierre Rosen
2003-11-25 21:48 ` Stephen Leake
2003-11-26  0:01   ` Ekkehard Morgenstern
2003-11-26  1:16     ` Jeffrey Carter
2003-11-26 15:10     ` Georg Bauhaus
2003-11-26 15:48     ` Stephen Leake
2003-11-26 16:24       ` Hyman Rosen
2003-11-26 17:58     ` Robert I. Eachus
2003-11-27  2:10       ` Ekkehard Morgenstern [this message]
2003-11-27 10:15         ` Ludovic Brenta
2003-11-27 18:35         ` Jeffrey Carter
2003-11-28  4:35           ` Hyman Rosen
2003-11-28  7:28             ` Vinzent 'Gadget' Hoefler
2003-11-28  8:46               ` Dale Stanbrough
2003-11-28 10:16                 ` Vinzent 'Gadget' Hoefler
2003-12-01 15:57             ` Martin Krischik
2003-12-01 16:47               ` Hyman Rosen
2003-12-03 18:35                 ` Martin Krischik
2003-12-01 21:13               ` Jeffrey Carter
2003-12-02  8:47               ` Dmitry A. Kazakov
2003-12-03  9:29                 ` Pascal Obry
2003-12-03 11:26                   ` Dmitry A. Kazakov
2003-12-03 12:49                     ` Ludovic Brenta
2003-12-03 13:41                       ` Dmitry A. Kazakov
2003-12-03 14:11                         ` Ludovic Brenta
2003-12-03 14:45                           ` Dmitry A. Kazakov
2003-12-03 15:44                         ` Hyman Rosen
2003-12-03 16:11                           ` Dmitry A. Kazakov
2003-12-03 18:20                           ` David C. Hoos
     [not found]                           ` <28eb01c3b9ca$25b18870$b101a8c0@sy.com>
2003-12-03 18:35                             ` Hyman Rosen
2003-12-03 20:05                           ` Randy Brukardt
2003-12-03 20:57                             ` Hyman Rosen
2003-12-03 21:16                               ` Hyman Rosen
2003-12-03 22:04                           ` Pascal Obry
2003-12-03 22:34                             ` Hyman Rosen
2003-12-04  1:23                               ` Robert I. Eachus
2003-12-04  7:15                                 ` Hyman Rosen
2003-12-04 17:43                                   ` Warren W. Gay VE3WWG
2003-12-04  8:55                                 ` Dmitry A. Kazakov
2003-12-04 19:13                                   ` Randy Brukardt
2003-12-04 19:29                                     ` Hyman Rosen
2003-12-04 21:32                                   ` Robert I. Eachus
2003-12-05  8:43                                     ` Dmitry A. Kazakov
2003-11-27 22:12         ` Robert I. Eachus
2003-11-28  6:37           ` Simon Wright
2003-11-30  2:51             ` Robert I. Eachus
2003-12-06  7:48 ` Chad Bremmon
2003-12-06 13:33   ` Jeff C,
2003-12-06 22:44   ` Hyman Rosen
2003-12-07  3:02     ` Chad Bremmon
2003-12-07  7:53       ` Hyman Rosen
2003-12-07 15:34         ` James Rogers
2003-12-07 18:30           ` Martin Krischik
2003-12-07 20:25             ` James Rogers
2003-12-08  3:36               ` Hyman Rosen
2003-12-08  4:42                 ` Chad Bremmon
2003-12-08  8:42                   ` Hyman Rosen
2003-12-08  9:34                     ` Dmitry A. Kazakov
2003-12-08 13:25                       ` Hyman Rosen
2003-12-08 15:05                         ` Dmitry A. Kazakov
2003-12-09  4:38                           ` Hyman Rosen
2003-12-09  8:19                             ` Dmitry A. Kazakov
2003-12-09 13:29                               ` Hyman Rosen
2003-12-09 14:36                                 ` Dmitry A. Kazakov
2003-12-09 15:05                                   ` Hyman Rosen
2003-12-09 15:59                                     ` Dmitry A. Kazakov
2003-12-09 16:41                                       ` Hyman Rosen
2003-12-10 11:32                                         ` Dmitry A. Kazakov
2003-12-10 15:27                                           ` Hyman Rosen
2003-12-10 17:15                                             ` Dmitry A. Kazakov
2003-12-08 17:55                       ` Chad Bremmon
2003-12-08 23:09                         ` Hyman Rosen
2003-12-09  8:26                         ` Dmitry A. Kazakov
2003-12-08 19:33                       ` Martin Krischik
2003-12-09  4:41                         ` Hyman Rosen
2003-12-08 17:27                     ` Chad Bremmon
2003-12-08 18:44                       ` Georg Bauhaus
2003-12-08 19:27                         ` Martin Krischik
2003-12-08 19:36                         ` Chad Bremmon
2003-12-09  4:43                           ` Hyman Rosen
2003-12-08 23:23                       ` Hyman Rosen
2003-12-08 19:25                     ` Martin Krischik
2003-12-07 21:29           ` Peter C. Chapin
2003-12-08  3:44             ` Hyman Rosen
2003-12-08  3:46           ` Hyman Rosen
2003-12-08  5:54             ` James Rogers
2003-12-08  8:45               ` Hyman Rosen
2003-12-07 17:39         ` Chad Bremmon
2003-12-08 23:39           ` Hyman Rosen
2003-12-09  2:36             ` Chad Bremmon
2003-12-09  4:52               ` Hyman Rosen
2003-12-09 11:24               ` Georg Bauhaus
2003-12-09 18:42                 ` Chad Bremmon
2003-12-09 20:11                   ` Hyman Rosen
2003-12-08 23:40           ` Hyman Rosen
replies disabled

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