comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert I. Eachus" <rieachus@comcast.net>
Subject: Re: abstract sub programs overriding
Date: Fri, 12 Mar 2004 18:02:54 -0500
Date: 2004-03-12T18:02:54-05:00	[thread overview]
Message-ID: <9_mdnfzBlfEC3M_d4p2dnA@comcast.com> (raw)
In-Reply-To: <1079013337.572283@master.nyc.kbcfp.com>

Hyman Rosen wrote:

>> procedure Initalize(Object: in out Child) is
>> begin
>>   Do_Something(Object);
>>   Initialize(Parent(Object));
>> end Initialize; 
> 
> Hmm. The understanding in C++ is that in a constructor, all of the base
> constructors have completed, so all facilities of the base classes are
> available to be used in the derived class constructors. I'm not saying
> that this first idiom you describe is wrong for Ada, but it does seem to
> force derived classes into having very intimate knowledge of the needs
> of their bases. What if initializing the child fields requires making
> calls to base methods?

Actually this version is used when the extension doesn't need to know 
anything about the elements (and operations) of the parent, if you need 
to access the parent fields you need to use the second option:
> 
>> procedure Initialize(Object: in out Child) is
>> begin
>>   Object := (Parent_Type with ...);
>>   Do_Something_Else(Object);
>> end Initialize;
> 
> Nice. In C++ it is highly discouraged to implement constructors via
> assignment (because it is fragile and error-prone). If I'm not mistaken,
> this code will cause Finalize to be called on Object before the assignment
> takes place, which means that it's possible for Finalize to be called on
> an object before any Initialize for it has completed.

No.  Finalize MAY be called on the Parent_Type part of the value being 
generated (but after the copy into the real Object).  If the Parent_Type 
is Limited_Controlled, then the value should be built in place, and no 
finalization will occur.  The other case where you will get a Finalize 
before Object has been completely Initialized, if some part of one of 
the Initialize calls raises an unhandled exception.

> I really have to stop
> thinking of Initialize/Adjust/Finalize as being equivalent to C++'s
> constructor/assignment/destructor. It may just be that I haven't gotten my
> mind around it properly, but it seems to me that Ada OO is significantly
> harder to understand and explain than Java's or C++'s, even (or especially)
> for simple cases.

Very much agree.  The Ada model is much more complex, since there was a 
lot of effort put into allowing nesting of controlled objects.  For the 
normal user, though, the real trick is that you may have no user defined 
Initialize procedure.  You give the components of the controlled object 
default initial values and you are done.

A better way to explain it is to point out that during development, the 
focus was on finalization.  The initialization in Ada 83 was sufficient 
for most users.  So for 99% of tagged types, there are no user defined 
Initialize procedures--and it works just fine.  Adjust is typically only 
used to provide deep copy semantics.

>> So yes, there are areas where user written code can access an object 
>> that has not yet been completely initialized.  But in practice, as a 
>> user you will find that once you get rid of any bugs (and exceptions) 
>> inside Intialize, Adjust, and Finalize, that code written by others, 
>> including the authors of types derived from your types, cannot mess up 
>> the invariants of your type.
> 
> I agree. But that's why I said that DK was wrong. Our discussion has been
> about code that runs during object construction and destruction. That is,
> the process of getting rid of the bugs and exceptions that you mention.

And what DK and I have been saying is that there is no problem, because 
of the "two stage" initialization of Ada tagged types.  Compilers can 
shortcut the process of building an object, if the compiler can prove 
that it makes no difference.  But other reading such an object in the 
debugger, the only way to get an uninitialized or abnormal subcomponent 
in a tagged object is to do something in that corrupts the subcomponent, 
then handle the exception and throw it away.  (And as I keep saying, if 
you throw the execption away without fixing the problem, you are 
definitely in "here be dragons" territory.  But that is true no matter 
where you do that.)

> That's not what I was talking about. I was saying that in a parent
> Initialize, the object could be view-converted to its classwide type,
> and then a dispatching call to could be made on the converted object
> which would wind up calling an overridden method of the child's type.

How many times do I have to say it.  You can try to DO that, but writing 
working code that does that is very hard--not impossible.  But if and 
when you get that code to compile, surprise! the object is initialized 
correctly.

The problem, or more appropriately what prevents the problem, is the 
order of elaboration rules in Ada.  To get the problem case, you need to 
create an object of the child type before the body of the parent package 
is elaborated.  So you need not only for the body of the package that 
declares the parent type to reference the child type, you need to create 
an object of the parent type before the main program is elaborated. 
There will be cases where, if you try to do this, there would be a 
possible elaboration order which the Ada rules don't allow.  (Mix the 
elaboration of procedures from the two package bodies.)  You can use 
nested calls and additional procedures in a third unit to make it all 
work.  But as I said then it all works.

So "down casting" to a child type in the body of the package which 
declares the parent is not illegal as such.  But if they are controlled, 
and you have different explicit Intialize procedures for the two types, 
and you create objects before the main program executes, it is VERY hard 
to get the resulting code to link.

> Think of the template-method design pattern for example. (This would
> be in your idiom one code, but with the parent's Initialize called
> *before* the Do_Something(Object), because Do_Something requires that
> its base classes be completely set up.) So overridden methods could
> wind up being called on incompletely prepared objects. This can't
> happen in C++. There, the dispatching would only go to methods of the
> class whose constructor or destructor is running. If such a method is
> abstract, the implementation generally arranges for the program to
> abort.

Again, it is very easy and natural in most cases.  Even if you have two 
explicit Initialize procedures, which in Ada is rare, the only problem 
is if, as above, Initialize for the parent requires the body of the 
child type to be elaborated, and there are objects of the type created 
before the main program starts executing.  Doing all of this is very bad 
form.  Doing one or two of the three is not a problem.  But it is 
usually referencing the body of the child package from the body of the 
parent package that Ada programmers avoid.  In Ada, elaboration order 
issues are an emergent property of a program as a whole.  There are a 
few rules though that you can follow to avoid ever having elaboration 
order (or compile order problems) this is one of them.  If for some 
reason you have to break it, do so.  But it will usually be painful to 
get right.

-- 

                                          Robert I. Eachus

"The only thing necessary for the triumph of evil is for good men to do 
nothing." --Edmund Burke




  reply	other threads:[~2004-03-12 23:02 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-02 19:01 abstract sub programs overriding Evangelista Sami
2004-03-03  1:43 ` Stephen Leake
2004-03-05 15:02   ` Evangelista Sami
2004-03-05 16:15     ` Marius Amado Alves
2004-03-08 18:54       ` Adam Beneschan
2004-03-08 23:42         ` Marius Amado Alves
2004-03-05 16:26     ` Marius Amado Alves
2004-03-06  9:31       ` Simon Wright
2004-03-06 15:18         ` Evangelista Sami
2004-03-06 19:09           ` Marius Amado Alves
2004-03-07 12:35             ` Simon Wright
2004-03-07 13:39               ` Marius Amado Alves
2004-03-08 19:08               ` Adam Beneschan
2004-03-08 20:03                 ` Hyman Rosen
2004-03-09  8:51                   ` Dmitry A. Kazakov
2004-03-09 13:34                     ` Hyman Rosen
2004-03-09 14:49                       ` Dmitry A. Kazakov
2004-03-09 15:14                         ` Hyman Rosen
2004-03-09 15:56                           ` Dmitry A. Kazakov
2004-03-09 16:32                             ` Hyman Rosen
2004-03-10  9:32                               ` Dmitry A. Kazakov
2004-03-10 13:08                                 ` Hyman Rosen
2004-03-10 14:58                                   ` Robert I. Eachus
2004-03-10 16:00                                     ` Hyman Rosen
2004-03-10 18:07                                       ` Robert I. Eachus
2004-03-10 20:04                                         ` Hyman Rosen
2004-03-11  2:43                                           ` Robert I. Eachus
2004-03-11 13:55                                             ` Hyman Rosen
2004-03-12 23:02                                               ` Robert I. Eachus [this message]
2004-03-14 21:33                                                 ` Hyman Rosen
2004-03-15  5:59                                                   ` Robert I. Eachus
2004-03-15 14:39                                                     ` Hyman Rosen
2004-03-16 16:16                                                       ` Robert I. Eachus
2004-03-16 16:51                                                         ` Hyman Rosen
2004-03-16 19:54                                                         ` Hyman Rosen
2004-03-16 23:16                                                           ` Randy Brukardt
2004-03-17  1:54                                                           ` Robert I. Eachus
2004-03-16 23:14                                                         ` Randy Brukardt
2004-03-17  2:43                                                           ` Robert I. Eachus
2004-03-17 17:40                                                             ` Randy Brukardt
2004-03-18  2:39                                                               ` Robert I. Eachus
2004-03-18  5:57                                                                 ` Randy Brukardt
2004-03-18 15:03                                                                   ` Hyman Rosen
2004-03-18 20:32                                                                     ` Randy Brukardt
2004-03-19  3:59                                                                       ` Hyman Rosen
2004-03-19 19:37                                                                         ` Randy Brukardt
2004-03-16  6:00                                               ` Randy Brukardt
2004-03-11 10:09                                   ` Dmitry A. Kazakov
2004-03-11 14:10                                     ` Hyman Rosen
2004-03-11 14:59                                       ` Dmitry A. Kazakov
2004-03-11 15:40                                         ` Hyman Rosen
2004-03-11 16:28                                           ` Dmitry A. Kazakov
2004-03-11 17:26                                             ` Hyman Rosen
2004-03-12  8:53                                               ` Dmitry A. Kazakov
2004-03-12 13:09                                                 ` Hyman Rosen
2004-03-12 14:00                                                   ` Dmitry A. Kazakov
2004-03-12 14:56                                                     ` Hyman Rosen
2004-03-12 18:19                                                       ` Dmitry A. Kazakov
2004-03-12 18:34                                                         ` Hyman Rosen
2004-03-12 20:05                                                           ` Georg Bauhaus
2004-03-13 10:12                                                           ` Dmitry A. Kazakov
2004-03-12 18:07                                               ` Robert I. Eachus
2004-03-10 15:51                 ` Evangelista Sami
2004-03-11  1:38                   ` Dan Eilers
2004-03-06 23:20     ` Dan Eilers
2004-03-03 12:00 ` Marius Amado Alves
2004-03-13  7:51 ` Simon Wright
replies disabled

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