comp.lang.ada
 help / color / mirror / Atom feed
* Extending a type and Finalization
@ 2009-06-04 17:45 pascal.malaise
  2009-06-04 18:00 ` Hibou57 (Yannick Duchêne)
  2009-06-15  6:30 ` AdaMagica
  0 siblings, 2 replies; 14+ messages in thread
From: pascal.malaise @ 2009-06-04 17:45 UTC (permalink / raw)


Hi Ada experts,

I have defined a tagged type T in a package P.
In another package I want to extend it new attributes and interfaces.
  type TT is new P.T with... and ...
but the new attributes require Ada.Finalization and Limited_Controlled
is a tagged type (not an interface).

Can I extend a type and together define the finalization of the new
type, and how?

Thank you in advance



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

* Re: Extending a type and Finalization
  2009-06-04 17:45 Extending a type and Finalization pascal.malaise
@ 2009-06-04 18:00 ` Hibou57 (Yannick Duchêne)
  2009-06-04 19:33   ` Adam Beneschan
  2009-06-15  6:30 ` AdaMagica
  1 sibling, 1 reply; 14+ messages in thread
From: Hibou57 (Yannick Duchêne) @ 2009-06-04 18:00 UTC (permalink / raw)


On 4 juin, 19:45, pascal.mala...@gmail.com wrote:
> but the new attributes require Ada.Finalization and Limited_Controlled
> is a tagged type (not an interface).
When you talk about attributes, do you mean “components” of the
record ?

> Can I extend a type and together define the finalization of the new
> type, and how?
If you are indeed talking about the record's components, then you are
not required to make the whole record controlled. You can do it on
individual compononents which requires this.



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

* Re: Extending a type and Finalization
  2009-06-04 18:00 ` Hibou57 (Yannick Duchêne)
@ 2009-06-04 19:33   ` Adam Beneschan
  2009-06-04 20:06     ` Dmitry A. Kazakov
  2009-06-05 11:29     ` malaise
  0 siblings, 2 replies; 14+ messages in thread
From: Adam Beneschan @ 2009-06-04 19:33 UTC (permalink / raw)


On Jun 4, 11:00 am, Hibou57 (Yannick Duchêne)
<yannick_duch...@yahoo.fr> wrote:
> On 4 juin, 19:45, pascal.mala...@gmail.com wrote:> but the new attributes require Ada.Finalization and Limited_Controlled
> > is a tagged type (not an interface).
>
> When you talk about attributes, do you mean “components” of the
> record ?
>
> > Can I extend a type and together define the finalization of the new
> > type, and how?
>
> If you are indeed talking about the record's components, then you are
> not required to make the whole record controlled. You can do it on
> individual compononents which requires this.

In addition to making an individual component a Limited_Controlled
type, you can use trickery using access discriminants to allow the
Initialize and Finalize routines to access the entire record.
Assuming P.T is limited, you can define something like:

   type Control_Type (Ref : access P.T'Class) is new
       Ada.Finalization.Limited_Controlled with null record;

   overriding procedure Initialize (Obj : in out Control_Type);
   overriding procedure Finalize   (Obj : in out Control_Type);

And then when defining TT:

   type TT is new P.T with record
      Control : Control_Type (TT'Access);
      ...
   end record;

Then when you declare an object of type TT, Initialize will be called
on the Control component, and the access discriminant Ref will give
you access to the entire record inside the Initialize and Finalize
routines.

(This idea isn't mine.  It might be Matthew Heaney's, but I'm not
sure.  The Control_Type declaration was adapted from a "shapes"
demonstration program, but I'm not sure where it came from.)

However, if it's possible to go back and change P.T to make it a type
derived from Limited_Controlled, that would be preferable, I think.
The default Initialize and Finalize routines will be null, so doing
this shouldn't change the semantics of the rest of the program any,
although it will add some overhead.

                                   -- Adam




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

* Re: Extending a type and Finalization
  2009-06-04 19:33   ` Adam Beneschan
@ 2009-06-04 20:06     ` Dmitry A. Kazakov
  2009-06-04 21:18       ` Adam Beneschan
  2009-06-05 11:29     ` malaise
  1 sibling, 1 reply; 14+ messages in thread
From: Dmitry A. Kazakov @ 2009-06-04 20:06 UTC (permalink / raw)


On Thu, 4 Jun 2009 12:33:04 -0700 (PDT), Adam Beneschan wrote:

> In addition to making an individual component a Limited_Controlled
> type, you can use trickery using access discriminants to allow the
> Initialize and Finalize routines to access the entire record.
> Assuming P.T is limited, you can define something like:
> 
>    type Control_Type (Ref : access P.T'Class) is new
>        Ada.Finalization.Limited_Controlled with null record;
> 
>    overriding procedure Initialize (Obj : in out Control_Type);
>    overriding procedure Finalize   (Obj : in out Control_Type);
> 
> And then when defining TT:
> 
>    type TT is new P.T with record
>       Control : Control_Type (TT'Access);
>       ...
>    end record;
> 
> Then when you declare an object of type TT, Initialize will be called
> on the Control component, and the access discriminant Ref will give
> you access to the entire record inside the Initialize and Finalize
> routines.
> 
> (This idea isn't mine.  It might be Matthew Heaney's, but I'm not
> sure.  The Control_Type declaration was adapted from a "shapes"
> demonstration program, but I'm not sure where it came from.)

I am not sure if this pattern is safe. What gives a guaranty that other
components of TT are initialized before the Initialize gets called on
Control and finalized after the Finalize gets called? Otherwise you might
access broken components of TT. It would be a hell to track down such an
error.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Extending a type and Finalization
  2009-06-04 20:06     ` Dmitry A. Kazakov
@ 2009-06-04 21:18       ` Adam Beneschan
  2009-06-05  9:11         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 14+ messages in thread
From: Adam Beneschan @ 2009-06-04 21:18 UTC (permalink / raw)


On Jun 4, 1:06 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 4 Jun 2009 12:33:04 -0700 (PDT), Adam Beneschan wrote:
> > In addition to making an individual component a Limited_Controlled
> > type, you can use trickery using access discriminants to allow the
> > Initialize and Finalize routines to access the entire record.
> > Assuming P.T is limited, you can define something like:
>
> >    type Control_Type (Ref : access P.T'Class) is new
> >        Ada.Finalization.Limited_Controlled with null record;
>
> >    overriding procedure Initialize (Obj : in out Control_Type);
> >    overriding procedure Finalize   (Obj : in out Control_Type);
>
> > And then when defining TT:
>
> >    type TT is new P.T with record
> >       Control : Control_Type (TT'Access);
> >       ...
> >    end record;
>
> > Then when you declare an object of type TT, Initialize will be called
> > on the Control component, and the access discriminant Ref will give
> > you access to the entire record inside the Initialize and Finalize
> > routines.
>
> > (This idea isn't mine.  It might be Matthew Heaney's, but I'm not
> > sure.  The Control_Type declaration was adapted from a "shapes"
> > demonstration program, but I'm not sure where it came from.)
>
> I am not sure if this pattern is safe. What gives a guaranty that other
> components of TT are initialized before the Initialize gets called on
> Control and finalized after the Finalize gets called?

RM 7.6(12)

                            -- Adam




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

* Re: Extending a type and Finalization
  2009-06-04 21:18       ` Adam Beneschan
@ 2009-06-05  9:11         ` Dmitry A. Kazakov
  2009-06-05 14:48           ` Adam Beneschan
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry A. Kazakov @ 2009-06-05  9:11 UTC (permalink / raw)


On Thu, 4 Jun 2009 14:18:41 -0700 (PDT), Adam Beneschan wrote:

> On Jun 4, 1:06�pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> On Thu, 4 Jun 2009 12:33:04 -0700 (PDT), Adam Beneschan wrote:
>>> In addition to making an individual component a Limited_Controlled
>>> type, you can use trickery using access discriminants to allow the
>>> Initialize and Finalize routines to access the entire record.
>>> Assuming P.T is limited, you can define something like:
>>
>>> � �type Control_Type (Ref : access P.T'Class) is new
>>> � � � �Ada.Finalization.Limited_Controlled with null record;
>>
>>> � �overriding procedure Initialize (Obj : in out Control_Type);
>>> � �overriding procedure Finalize � (Obj : in out Control_Type);
>>
>>> And then when defining TT:
>>
>>> � �type TT is new P.T with record
>>> � � � Control : Control_Type (TT'Access);
>>> � � � ...
>>> � �end record;
>>
>>> Then when you declare an object of type TT, Initialize will be called
>>> on the Control component, and the access discriminant Ref will give
>>> you access to the entire record inside the Initialize and Finalize
>>> routines.
>>
>>> (This idea isn't mine. �It might be Matthew Heaney's, but I'm not
>>> sure. �The Control_Type declaration was adapted from a "shapes"
>>> demonstration program, but I'm not sure where it came from.)
>>
>> I am not sure if this pattern is safe. What gives a guaranty that other
>> components of TT are initialized before the Initialize gets called on
>> Control and finalized after the Finalize gets called?
> 
> RM 7.6(12)

Then it should rather be:

 � �type TT is new P.T with record
 � � � ...
 � � � Control : Control_Type (TT'Access);  -- The last component
 � �end record;

BTW, it seems that this pattern has a more consistent behavior upon
extension than Ada.Finalization itself:

   type TTT;
 � type TTT_Hook (Ref : not null access TTT'Class) is new
 � � �Ada.Finalization.Limited_Controlled with null record;
 � overriding procedure Initialize (Obj : in out TTT_Hook);
 � overriding procedure Finalize � (Obj : in out TTT_Hook);

 � type TTT is new TT with record
 � � �...
 � � �Hook : TTT_Hook (TTT'Access);
 � end record;

Unlikely to Ada.Finalize from the Initialize of TTT_Hook we do not call to
the Initialize of Control_Type, because it has been called.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Extending a type and Finalization
  2009-06-04 19:33   ` Adam Beneschan
  2009-06-04 20:06     ` Dmitry A. Kazakov
@ 2009-06-05 11:29     ` malaise
  2009-06-05 12:21       ` Ludovic Brenta
  1 sibling, 1 reply; 14+ messages in thread
From: malaise @ 2009-06-05 11:29 UTC (permalink / raw)


On 4 juin, 21:33, Adam Beneschan <a...@irvine.com> wrote:


> In addition to making an individual component a Limited_Controlled
> type, you can use trickery using access discriminants to allow the
> Initialize and Finalize routines to access the entire record.
I have done that and it works (at least it compiles). Thank's.

> However, if it's possible to go back and change P.T to make it a type
> derived from Limited_Controlled, that would be preferable, I think.
> The default Initialize and Finalize routines will be null, so doing
> this shouldn't change the semantics of the rest of the program any,
> although it will add some overhead.
I face a problem when doing that, despite it should be
straightforward!.

I declare P.T as "new Ada.Finalization.Controlled with record ..." and
I don't define Finalize for it.
Then in Pp I declare Tt as "new P.T with record ..." and I declare an
overriding procedure Finalize (V : in out Tt) and its body in Pp body.
It does not compile, with error: 'subprogram "Finalize" is not
overriding'

Same if I define in P a Finalize for T.

Any idea?

------------------------------
with Ada.Finalization;
package P is
  type T is tagged private;
private
  type T is new Ada.Finalization.Controlled with record
    I : Integer;
  end record;
end P;

with P;
package Pp is
  type Tt is tagged private;
private
  type Tt is new P.T with record
    Ii : Integer;
  end record;
  overriding procedure Finalize (V : in out Tt);
end Pp;

package body Pp is
  overriding procedure Finalize (V : in out Tt) is
  begin
    null;
  end Finalize;
end Pp;




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

* Re: Extending a type and Finalization
  2009-06-05 11:29     ` malaise
@ 2009-06-05 12:21       ` Ludovic Brenta
  2009-06-05 13:02         ` malaise
  0 siblings, 1 reply; 14+ messages in thread
From: Ludovic Brenta @ 2009-06-05 12:21 UTC (permalink / raw)


Pascal Malaise wrote on comp.lang.ada:
> I declare P.T as "new Ada.Finalization.Controlled with record ..." and
> I don't define Finalize for it.
> Then in Pp I declare Tt as "new P.T with record ..." and I declare an
> overriding procedure Finalize (V : in out Tt) and its body in Pp body.
> It does not compile, with error: 'subprogram "Finalize" is not
> overriding'
>
> Same if I define in P a Finalize for T.
>
> Any idea?
>
> ------------------------------
> with Ada.Finalization;
> package P is
>   type T is tagged private;
> private
>   type T is new Ada.Finalization.Controlled with record
>     I : Integer;
>   end record;
> end P;
>
> with P;
> package Pp is
>   type Tt is tagged private;
> private
>   type Tt is new P.T with record
>     Ii : Integer;
>   end record;
>   overriding procedure Finalize (V : in out Tt);
> end Pp;
>
> package body Pp is
>   overriding procedure Finalize (V : in out Tt) is
>   begin
>     null;
>   end Finalize;
> end Pp;

That's because P.T is a *private* record extension of
Ada.Finalization.Controlled. Package PP cannot see that P.T derives
from it.

Solution 1: rename PP to P.P, a child package of P so it can see the
private part of P.

Solution 2: make P.T a public record extension:

type T is new Ada.Finalization.Controlled with private;

But I recommend that you *not* derive P.T from any other type; use a
mixin instead. Making a type controlled is not a good enough reason
for making it tagged.

--
Ludovic Brenta.



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

* Re: Extending a type and Finalization
  2009-06-05 12:21       ` Ludovic Brenta
@ 2009-06-05 13:02         ` malaise
  2009-06-05 13:14           ` Ludovic Brenta
  0 siblings, 1 reply; 14+ messages in thread
From: malaise @ 2009-06-05 13:02 UTC (permalink / raw)


On 5 juin, 14:21, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
> Pascal Malaise wrote on comp.lang.ada:
>
>
>
> > I declare P.T as "new Ada.Finalization.Controlled with record ..." and
> > I don't define Finalize for it.
> > Then in Pp I declare Tt as "new P.T with record ..." and I declare an
> > overriding procedure Finalize (V : in out Tt) and its body in Pp body.
> > It does not compile, with error: 'subprogram "Finalize" is not
> > overriding'
>
> > Same if I define in P a Finalize for T.
>
> > Any idea?
>
> > ------------------------------
> > with Ada.Finalization;
> > package P is
> >   type T is tagged private;
> > private
> >   type T is new Ada.Finalization.Controlled with record
> >     I : Integer;
> >   end record;
> > end P;
>
> > with P;
> > package Pp is
> >   type Tt is tagged private;
> > private
> >   type Tt is new P.T with record
> >     Ii : Integer;
> >   end record;
> >   overriding procedure Finalize (V : in out Tt);
> > end Pp;
>
> > package body Pp is
> >   overriding procedure Finalize (V : in out Tt) is
> >   begin
> >     null;
> >   end Finalize;
> > end Pp;
>
> That's because P.T is a *private* record extension of
> Ada.Finalization.Controlled. Package PP cannot see that P.T derives
> from it.
>
> Solution 1: rename PP to P.P, a child package of P so it can see the
> private part of P.
>
> Solution 2: make P.T a public record extension:
>
> type T is new Ada.Finalization.Controlled with private;
>
> But I recommend that you *not* derive P.T from any other type; use a
> mixin instead. Making a type controlled is not a good enough reason
> for making it tagged.
>
> --
> Ludovic Brenta.

Thank you Ludovic. Solution 2 is fine for me.

Concerning your recommendation, I think that the following is
compliant, or did I misunderstand something?
type T is new Ada.Finalization.Controlled with record
    I : Integer;
  end record;
end P;



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

* Re: Extending a type and Finalization
  2009-06-05 13:02         ` malaise
@ 2009-06-05 13:14           ` Ludovic Brenta
  2009-06-05 13:32             ` malaise
  0 siblings, 1 reply; 14+ messages in thread
From: Ludovic Brenta @ 2009-06-05 13:14 UTC (permalink / raw)


Pascal Malaise wrote on comp.lang.ada:
> Thank you Ludovic. Solution 2 is fine for me.
>
> Concerning your recommendation, I think that the following is
> compliant, or did I misunderstand something?
> type T is new Ada.Finalization.Controlled with record
>     I : Integer;
>   end record;
> end P;

No, that complies with Dmitry's recommendation but not with mine or
Jeffrey's. I prefer and recommend composition unless there is a
compelling reason to use type extension. Adam's post earlier in this
thread describes the composition approach.

--
Ludovic Brenta.



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

* Re: Extending a type and Finalization
  2009-06-05 13:14           ` Ludovic Brenta
@ 2009-06-05 13:32             ` malaise
  0 siblings, 0 replies; 14+ messages in thread
From: malaise @ 2009-06-05 13:32 UTC (permalink / raw)


On 5 juin, 15:14, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
> Pascal Malaise wrote on comp.lang.ada:
>
> > Thank you Ludovic. Solution 2 is fine for me.
>
> > Concerning your recommendation, I think that the following is
> > compliant, or did I misunderstand something?
> > type T is new Ada.Finalization.Controlled with record
> >     I : Integer;
> >   end record;
> > end P;
>
> No, that complies with Dmitry's recommendation but not with mine or
> Jeffrey's. I prefer and recommend composition unless there is a
> compelling reason to use type extension. Adam's post earlier in this
> thread describes the composition approach.
>
> --
> Ludovic Brenta.

I need to make visible that T is an extension of Controlled (as we
have seen earlier).
I want to hide, make private, the component I of T.
So the only solution I see is (but this is not a complelling reason):

  type T is new Ada.Finalization.Controlled with private;
private
  type T is new Ada.Finalization.Controlled with record
    I : Integer;
  end record;



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

* Re: Extending a type and Finalization
  2009-06-05  9:11         ` Dmitry A. Kazakov
@ 2009-06-05 14:48           ` Adam Beneschan
  2009-06-05 17:15             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 14+ messages in thread
From: Adam Beneschan @ 2009-06-05 14:48 UTC (permalink / raw)


On Jun 5, 2:11 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> >> I am not sure if this pattern is safe. What gives a guaranty that other
> >> components of TT are initialized before the Initialize gets called on
> >> Control and finalized after the Finalize gets called?
>
> > RM 7.6(12)
>
> Then it should rather be:
>
>     type TT is new P.T with record
>        ...
>        Control : Control_Type (TT'Access);  -- The last component
>     end record;

No; the rule I cited makes certain that components with self-
referential access discriminant constraints are always initialized
last and finalized first, regardless of whether they appear before or
after other components in the extension part.  (Order matters only
when you have more than one component that has a discriminant
constraint like this.)

                              -- Adam




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

* Re: Extending a type and Finalization
  2009-06-05 14:48           ` Adam Beneschan
@ 2009-06-05 17:15             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 14+ messages in thread
From: Dmitry A. Kazakov @ 2009-06-05 17:15 UTC (permalink / raw)


On Fri, 5 Jun 2009 07:48:52 -0700 (PDT), Adam Beneschan wrote:

> (Order matters only
> when you have more than one component that has a discriminant
> constraint like this.)

Yes, this is why it must be the last component, presuming that other
components, if any, do not misuse their access discriminant for the same
purpose of initialization.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Extending a type and Finalization
  2009-06-04 17:45 Extending a type and Finalization pascal.malaise
  2009-06-04 18:00 ` Hibou57 (Yannick Duchêne)
@ 2009-06-15  6:30 ` AdaMagica
  1 sibling, 0 replies; 14+ messages in thread
From: AdaMagica @ 2009-06-15  6:30 UTC (permalink / raw)


I published a paper in Ada Letters, Volume XIX, Number 4, December
1999, which discusses adding finalization to uncontrolled types in
detail.

You can find it here http://www.christ-usch-grein.homepage.t-online.de/Ada/Finalization.html
(with some minor corrections and updates).



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

end of thread, other threads:[~2009-06-15  6:30 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-04 17:45 Extending a type and Finalization pascal.malaise
2009-06-04 18:00 ` Hibou57 (Yannick Duchêne)
2009-06-04 19:33   ` Adam Beneschan
2009-06-04 20:06     ` Dmitry A. Kazakov
2009-06-04 21:18       ` Adam Beneschan
2009-06-05  9:11         ` Dmitry A. Kazakov
2009-06-05 14:48           ` Adam Beneschan
2009-06-05 17:15             ` Dmitry A. Kazakov
2009-06-05 11:29     ` malaise
2009-06-05 12:21       ` Ludovic Brenta
2009-06-05 13:02         ` malaise
2009-06-05 13:14           ` Ludovic Brenta
2009-06-05 13:32             ` malaise
2009-06-15  6:30 ` AdaMagica

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