comp.lang.ada
 help / color / mirror / Atom feed
* Enforcing initialization protocol for protected type
@ 2009-09-07 15:15 Maciej Sobczak
  2009-09-07 17:01 ` Georg Bauhaus
  2009-09-10 16:39 ` Per Sandberg
  0 siblings, 2 replies; 13+ messages in thread
From: Maciej Sobczak @ 2009-09-07 15:15 UTC (permalink / raw)


Consider the Needs_Constructor type from the code example in the Ada
wikibook:

http://en.wikibooks.org/wiki/Ada_Programming/Types/limited#Initialisi...

Is it possible to ensure a given initialization protocol for protected
types as well?

The problem is that protected types cannot have unknown discriminants.
How can I ensure that objects of a given protected type are always
initialized with a call to proper constructor function?

Note that wrapping a protected object in another one (presumably
limited and private) would limit the possibility to perform timed
entry calls on the target protected object and preserving this
possibility is essential in my actual use case.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: Enforcing initialization protocol for protected type
  2009-09-07 15:15 Enforcing initialization protocol for protected type Maciej Sobczak
@ 2009-09-07 17:01 ` Georg Bauhaus
  2009-09-07 20:19   ` Maciej Sobczak
  2009-09-10 16:39 ` Per Sandberg
  1 sibling, 1 reply; 13+ messages in thread
From: Georg Bauhaus @ 2009-09-07 17:01 UTC (permalink / raw)


Maciej Sobczak schrieb:
> Consider the Needs_Constructor type from the code example in the Ada
> wikibook:
> 
> http://en.wikibooks.org/wiki/Ada_Programming/Types/limited#Initialisi...
> 
> Is it possible to ensure a given initialization protocol for protected
> types as well?

The following is not using, I guess, your original
idea directly.  But it requires that the a proper context
be set up.  Then, the PO will initialize itself from
the context.  Context is passed in via known discriminants:

   -- method A, function pointer



   type Status_A is private;
   type A_Maker is access function return Status_A;

   -- method B, O-O construction



   type Status_B is private;
   package OO is
      type B_Maker is tagged private;

      function Make_B(Context: B_Maker) return Status_B;
   private
      type B_Maker is tagged record
         null;
      end record;
   end OO;

   type B_Maker_Ref is access OO.B_Maker'Class;

   protected type PO
     (First_A : not null A_Maker;
      First_B : not null B_Maker_Ref)
   is
      entry One;
      entry Two;
   private
      Data_A: Status_A := First_A.all;
      Data_B: Status_B := First_B.Make_B;
   end PO;



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

* Re: Enforcing initialization protocol for protected type
  2009-09-07 17:01 ` Georg Bauhaus
@ 2009-09-07 20:19   ` Maciej Sobczak
  2009-09-10 17:07     ` Georg Bauhaus
  2009-09-11  5:01     ` AdaMagica
  0 siblings, 2 replies; 13+ messages in thread
From: Maciej Sobczak @ 2009-09-07 20:19 UTC (permalink / raw)


On 7 Wrz, 19:01, Georg Bauhaus <rm.dash-bauh...@futureapps.de> wrote:

> The following is not using, I guess, your original
> idea directly.  But it requires that the a proper context
> be set up.  Then, the PO will initialize itself from
> the context.  Context is passed in via known discriminants:
[...]

I see. I guess that in addition to passing the factory (function on
object, as in your example), the state itself can be passed via
discriminant as well.
This would leave the factory call at the user side (note that in your
example it was the protected object itself that called the factory),
which would give more control on factory call parameters and such.

type State is private;
type State_Ptr is access State;

function Make_PO return State_Ptr;
function Make_PO (Some : T; Parameters : T) return State_Ptr;
-- ...

protected type PO (S : State_Ptr) is
-- ...
private
    St : State_Ptr := S;
end PO;

so that the typical creation pattern would be:

X : PO (Make_PO);
Y : PO (Make_PO (ABC, DEF));

This, however, opens another question: controlled finalization of
protected types to release the state object, if it was allocated
dynamically. Oops.
But a controlled component of the protected type can take care of
that.
Does it make sense?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: Enforcing initialization protocol for protected type
  2009-09-07 15:15 Enforcing initialization protocol for protected type Maciej Sobczak
  2009-09-07 17:01 ` Georg Bauhaus
@ 2009-09-10 16:39 ` Per Sandberg
  2009-09-14 21:15   ` Adam Beneschan
  1 sibling, 1 reply; 13+ messages in thread
From: Per Sandberg @ 2009-09-10 16:39 UTC (permalink / raw)


The following will solve your problem but there is a catch.
The only compiler that will fix it is to my knowledge the most bleeding
edge gnat.
/Per

-----------------------------
       package p is
          type Protected_t;
          type initializer_t (Wrapped : not null access  Protected_t)
            is new ada.Finalization.Limited_Controlled with null record;

          procedure Initialize (self : in out initializer_t);
          procedure Finalize   (self : in out initializer_t);

          protected type Protected_t is
             entry tick;
             procedure Initialize;
             procedure finalize;
          private
             initializer : initializer_t (Protected_t'access);
          end;
       end p;

       package body p is
          protected body Protected_t is
             entry tick when True is begin
                null;
             end;
             procedure Initialize is
             begin
                null;
             end;
             procedure finalize is
             begin
                null;
             end;
          end;
          procedure Initialize (self : in out initializer_t) is
          begin
             self.Wrapped.Initialize;
          end;
          procedure Finalize   (self : in out initializer_t) is
          begin
             self.Wrapped.Initialize;
          end;
       end p;

Maciej Sobczak wrote:
> Consider the Needs_Constructor type from the code example in the Ada
> wikibook:
> 
> http://en.wikibooks.org/wiki/Ada_Programming/Types/limited#Initialisi...
> 
> Is it possible to ensure a given initialization protocol for protected
> types as well?
> 
> The problem is that protected types cannot have unknown discriminants.
> How can I ensure that objects of a given protected type are always
> initialized with a call to proper constructor function?
> 
> Note that wrapping a protected object in another one (presumably
> limited and private) would limit the possibility to perform timed
> entry calls on the target protected object and preserving this
> possibility is essential in my actual use case.
> 
> --
> Maciej Sobczak * www.msobczak.com * www.inspirel.com
> 
> Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: Enforcing initialization protocol for protected type
  2009-09-07 20:19   ` Maciej Sobczak
@ 2009-09-10 17:07     ` Georg Bauhaus
  2009-09-11  5:01     ` AdaMagica
  1 sibling, 0 replies; 13+ messages in thread
From: Georg Bauhaus @ 2009-09-10 17:07 UTC (permalink / raw)


Maciej Sobczak schrieb:

> This would leave the factory call at the user side (note that in your
> example it was the protected object itself that called the factory),
> which would give more control on factory call parameters and such.
> 
> type State is private;
> type State_Ptr is access State;
> 
> function Make_PO return State_Ptr;
> function Make_PO (Some : T; Parameters : T) return State_Ptr;
> -- ...
> 
> protected type PO (S : State_Ptr) is
> -- ...
> private
>     St : State_Ptr := S;
> end PO;
> 
> so that the typical creation pattern would be:
> 
> X : PO (Make_PO);
> Y : PO (Make_PO (ABC, DEF));
> 
> This, however, opens another question: controlled finalization of
> protected types to release the state object, if it was allocated
> dynamically. Oops.
> But a controlled component of the protected type can take care of
> that.
> Does it make sense?

Yes, state pointer makes sense.

OTOH, you could preserve both, copy semantics for the state if
copying state makes sense and is desirable, and flexible
client side operation of the state factory by defining a two-faced
factory interface:

- one operation is for the protected object. Returns a computed state
  value as a "result" of the factory's operation

- as many operations as desired for computing this inital state.
  This is for the factory operators other that the protected object



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

* Re: Enforcing initialization protocol for protected type
  2009-09-07 20:19   ` Maciej Sobczak
  2009-09-10 17:07     ` Georg Bauhaus
@ 2009-09-11  5:01     ` AdaMagica
  2009-09-11  9:03       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 13+ messages in thread
From: AdaMagica @ 2009-09-11  5:01 UTC (permalink / raw)


On 7 Sep., 22:19, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> type State is private;
> type State_Ptr is access State;
>
> function Make_PO return State_Ptr;
> function Make_PO (Some : T; Parameters : T) return State_Ptr;
> -- ...
>
> protected type PO (S : State_Ptr) is
> -- ...
> private
>     St : State_Ptr := S;
> end PO;
>
> so that the typical creation pattern would be:
>
> X : PO (Make_PO);
> Y : PO (Make_PO (ABC, DEF));
>
> This, however, opens another question: controlled finalization of
> protected types to release the state object, if it was allocated
> dynamically. Oops.

Use an access discriminant of an anonymous type and you will get a
coextension that is reclaimed automatically when the object goes out
of scope, see RM 3.10(14.3/2,14.4/2) [or in the newest draft of the
Amendment 2, (14.1/3,14.4/3), which is a bit clearer].

See also RM 3.7(1.c/2..1.e/2).

> But a controlled component of the protected type can take care of
> that.
> Does it make sense?
>
> --
> Maciej Sobczak *www.msobczak.com*www.inspirel.com
>
> Database Access Library for Ada:www.inspirel.com/soci-ada



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

* Re: Enforcing initialization protocol for protected type
  2009-09-11  5:01     ` AdaMagica
@ 2009-09-11  9:03       ` Dmitry A. Kazakov
  2009-09-11 15:25         ` AdaMagica
  0 siblings, 1 reply; 13+ messages in thread
From: Dmitry A. Kazakov @ 2009-09-11  9:03 UTC (permalink / raw)


On Thu, 10 Sep 2009 22:01:17 -0700 (PDT), AdaMagica wrote:

> On 7 Sep., 22:19, Maciej Sobczak <see.my.homep...@gmail.com> wrote:

>> This, however, opens another question: controlled finalization of
>> protected types to release the state object, if it was allocated
>> dynamically. Oops.
> 
> Use an access discriminant of an anonymous type and you will get a
> coextension that is reclaimed automatically when the object goes out
> of scope, see RM 3.10(14.3/2,14.4/2) [or in the newest draft of the
> Amendment 2, (14.1/3,14.4/3), which is a bit clearer].
> 
> See also RM 3.7(1.c/2..1.e/2).

Hmm, what do you mean by that? When the discriminant's type is an anonymous
access it is still declared at the declaration point of the type. It is not
the declaration point of an object. So if the discriminant is obtained by
the allocator new it will not be destroyed when the object leaves the
scope. It will when the type does. If these scopes are different, the
compiler will complain that the type in the allocator has a deeper level.

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



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

* Re: Enforcing initialization protocol for protected type
  2009-09-11  9:03       ` Dmitry A. Kazakov
@ 2009-09-11 15:25         ` AdaMagica
  2009-09-11 16:27           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 13+ messages in thread
From: AdaMagica @ 2009-09-11 15:25 UTC (permalink / raw)


On 11 Sep., 11:03, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Thu, 10 Sep 2009 22:01:17 -0700 (PDT), AdaMagica wrote:
> > On 7 Sep., 22:19, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> >> This, however, opens another question: controlled finalization of
> >> protected types to release the state object, if it was allocated
> >> dynamically. Oops.
>
> > Use an access discriminant of an anonymous type and you will get a
> > coextension that is reclaimed automatically when the object goes out
> > of scope, see RM 3.10(14.3/2,14.4/2) [or in the newest draft of the
> > Amendment 2, (14.1/3,14.4/3), which is a bit clearer].
>
> > See also RM 3.7(1.c/2..1.e/2).
>
> Hmm, what do you mean by that? When the discriminant's type is an anonymous
> access it is still declared at the declaration point of the type. It is not
> the declaration point of an object. So if the discriminant is obtained by
> the allocator new it will not be destroyed when the object leaves the
> scope. It will when the type does. If these scopes are different, the
> compiler will complain that the type in the allocator has a deeper level.

type Disc is ...

type Rec (D: access Disc) is record ...

Obj: Rec (new Disc);

The discriminant (a coextension of the object) will be deallocated
when Obj goes out of scope.

subtype ConRec is Rec (new Disc);

If I understand the RM correctly, the discriminant of objects of the
constrained subtype is no coextensions; it will be deallocated when
the subtype goes out of scope.



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

* Re: Enforcing initialization protocol for protected type
  2009-09-11 15:25         ` AdaMagica
@ 2009-09-11 16:27           ` Dmitry A. Kazakov
  2009-09-11 22:24             ` Randy Brukardt
  0 siblings, 1 reply; 13+ messages in thread
From: Dmitry A. Kazakov @ 2009-09-11 16:27 UTC (permalink / raw)


On Fri, 11 Sep 2009 08:25:56 -0700 (PDT), AdaMagica wrote:

> On 11 Sep., 11:03, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> On Thu, 10 Sep 2009 22:01:17 -0700 (PDT), AdaMagica wrote:
>>> On 7 Sep., 22:19, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
>>>> This, however, opens another question: controlled finalization of
>>>> protected types to release the state object, if it was allocated
>>>> dynamically. Oops.
>>
>>> Use an access discriminant of an anonymous type and you will get a
>>> coextension that is reclaimed automatically when the object goes out
>>> of scope, see RM 3.10(14.3/2,14.4/2) [or in the newest draft of the
>>> Amendment 2, (14.1/3,14.4/3), which is a bit clearer].
>>
>>> See also RM 3.7(1.c/2..1.e/2).
>>
>> Hmm, what do you mean by that? When the discriminant's type is an anonymous
>> access it is still declared at the declaration point of the type. It is not
>> the declaration point of an object. So if the discriminant is obtained by
>> the allocator new it will not be destroyed when the object leaves the
>> scope. It will when the type does. If these scopes are different, the
>> compiler will complain that the type in the allocator has a deeper level.
> 
> type Disc is ...
> 
> type Rec (D: access Disc) is record ...
> 
> Obj: Rec (new Disc);
> 
> The discriminant (a coextension of the object) will be deallocated
> when Obj goes out of scope.

OK I see. Anyway I would not use this design pattern because it would be a
source of countless errors very difficult to track down.

P.S. It looks like a language design bug. If allowed then at least it
should have been like:

   Obj: subtype Rec (new Disc);
      -- An anonymous subtype is declared for Obj

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



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

* Re: Enforcing initialization protocol for protected type
  2009-09-11 16:27           ` Dmitry A. Kazakov
@ 2009-09-11 22:24             ` Randy Brukardt
  2009-09-12  8:44               ` Dmitry A. Kazakov
  0 siblings, 1 reply; 13+ messages in thread
From: Randy Brukardt @ 2009-09-11 22:24 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:1rusjydws2ko.rpfwzoyv4bzj$.dlg@40tude.net...
...
> P.S. It looks like a language design bug. If allowed then at least it
> should have been like:
>
>   Obj: subtype Rec (new Disc);
>      -- An anonymous subtype is declared for Obj

I think most of us consider "coextensions" a language design bug. Indeed, 
that is about the nicest thing I can say about them. There are many of us 
who think that allocators of anonymous access types should simply be illegal 
(in all contexts), because what they mean currently depends so heavily on 
context and that makes them a maintenance nightmare (at best).

Morevoer, the rules for coextensions are a constantly shifting complex 
morrass. So, if you want to give yourself and your vendor a constant supply 
of headaches, then by all means use coextensions. Otherwise, I highly 
suggest you avoid them.

(For the record, Janus/Ada does not support coextensions -- recent versions 
make the allocators illegal since they don't have the correct semantics. 
Implementation is currently scheduled for approximately the year 2092. ;-)

                                               Randy.





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

* Re: Enforcing initialization protocol for protected type
  2009-09-11 22:24             ` Randy Brukardt
@ 2009-09-12  8:44               ` Dmitry A. Kazakov
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry A. Kazakov @ 2009-09-12  8:44 UTC (permalink / raw)


On Fri, 11 Sep 2009 17:24:57 -0500, Randy Brukardt wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
> news:1rusjydws2ko.rpfwzoyv4bzj$.dlg@40tude.net...
> ...
>> P.S. It looks like a language design bug. If allowed then at least it
>> should have been like:
>>
>>   Obj: subtype Rec (new Disc);
>>      -- An anonymous subtype is declared for Obj
> 
> I think most of us consider "coextensions" a language design bug. Indeed, 
> that is about the nicest thing I can say about them. There are many of us 
> who think that allocators of anonymous access types should simply be illegal 
> (in all contexts), because what they mean currently depends so heavily on 
> context and that makes them a maintenance nightmare (at best).

Yet strange semantic constructs keep on appearing in Ada. That is IMO
because people fail to face the "tragic" reality, that MI must be there,
that initialization must be handled properly, that discriminant is a
constraint and not a pointer, that protected type must be tagged and so on.

Look how an Ada programmers must twist his design just because protected
type cannot be derived from, or that no class-wide component can be put
into it.

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



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

* Re: Enforcing initialization protocol for protected type
  2009-09-10 16:39 ` Per Sandberg
@ 2009-09-14 21:15   ` Adam Beneschan
  2009-09-15  0:27     ` Randy Brukardt
  0 siblings, 1 reply; 13+ messages in thread
From: Adam Beneschan @ 2009-09-14 21:15 UTC (permalink / raw)


On Sep 10, 9:39 am, Per Sandberg <per.sandb...@bredband.net> wrote:
> The following will solve your problem but there is a catch.
> The only compiler that will fix it is to my knowledge the most bleeding
> edge gnat.
> /Per
>
> -----------------------------
>        package p is
>           type Protected_t;
>           type initializer_t (Wrapped : not null access  Protected_t)
>             is new ada.Finalization.Limited_Controlled with null record;
>
>           procedure Initialize (self : in out initializer_t);
>           procedure Finalize   (self : in out initializer_t);
>
>           protected type Protected_t is
>              entry tick;
>              procedure Initialize;
>              procedure finalize;
>           private
>              initializer : initializer_t (Protected_t'access);
>           end;
>        end p;
>
>        package body p is
>           protected body Protected_t is
>              entry tick when True is begin
>                 null;
>              end;
>              procedure Initialize is
>              begin
>                 null;
>              end;
>              procedure finalize is
>              begin
>                 null;
>              end;
>           end;
>           procedure Initialize (self : in out initializer_t) is
>           begin
>              self.Wrapped.Initialize;
>           end;
>           procedure Finalize   (self : in out initializer_t) is
>           begin
>              self.Wrapped.Initialize;

That last probably ought to be self.Wrapped.Finalize.

>           end;
>        end p;

By the way, I think this will work, but it does mean that a protected
action will be called on a protected object before the object is fully
initialized.  I've looked through the language rules and I'm not
convinced this is a problem.  In Ada 95, 3.3.1(18-19) appeared to mean
that the object was *created* before its components were initialized,
and I suspect that creating the protected object included creating its
entry queues and completing whatever else would be necessary so that
the protected action that takes place when the Initialize protected
subprogram was called could be completed successfully (including
servicing the entry queues as required by 9.5.1(7)).  In Ada 2005,
however, 3.3.1(18-19) have been merged into one paragraph, so that the
timing isn't quite as clear, depending on how you interpret the new
paragraph.  Any language lawyers care to comment?  Is Per's example
(with additional code as needed in the Initialize procedure)
guaranteed to work (as long as the Initialize protected procedure
doesn't reference any components with per-object constraints that
haven't yet been initialized), or is it ambiguous whether it will work
or not?

                                        -- Adam




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

* Re: Enforcing initialization protocol for protected type
  2009-09-14 21:15   ` Adam Beneschan
@ 2009-09-15  0:27     ` Randy Brukardt
  0 siblings, 0 replies; 13+ messages in thread
From: Randy Brukardt @ 2009-09-15  0:27 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message 
news:b9fde919-8c26-4b75-acfc-6b2a37bca968@u16g2000pru.googlegroups.com...
...
>  Any language lawyers care to comment?

No. :-)

>  Is Per's example (with additional code as needed in the Initialize 
> procedure)
> guaranteed to work (as long as the Initialize protected procedure
> doesn't reference any components with per-object constraints that
> haven't yet been initialized), or is it ambiguous whether it will work
> or not?

I don't want to strain my brain that much. But you ought to be able to 
figure it out using all of the rules of 3.3.1. The reason the 3.3.1(18-19) 
were combined is that those operations can be interleaved. The rules for the 
ordering are given by 3.3.1(20-20.4). Note that by default all of the 
operations can be evaluated in an arbitrary order, but there are enough 
restrictions to that to ensure that most things that you would expect to 
write can work.

Note that "default initialization" is how the queues and the like of a 
protected object get initialized. (Ada 95 did not define a term for this 
process, but that caused duplication of wording all over the Standard, and 
*that* caused inconsistent rules.) I don't think there are any semantics 
attached to "creation".

                                     Randy.




                                        -- Adam





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

end of thread, other threads:[~2009-09-15  0:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-07 15:15 Enforcing initialization protocol for protected type Maciej Sobczak
2009-09-07 17:01 ` Georg Bauhaus
2009-09-07 20:19   ` Maciej Sobczak
2009-09-10 17:07     ` Georg Bauhaus
2009-09-11  5:01     ` AdaMagica
2009-09-11  9:03       ` Dmitry A. Kazakov
2009-09-11 15:25         ` AdaMagica
2009-09-11 16:27           ` Dmitry A. Kazakov
2009-09-11 22:24             ` Randy Brukardt
2009-09-12  8:44               ` Dmitry A. Kazakov
2009-09-10 16:39 ` Per Sandberg
2009-09-14 21:15   ` Adam Beneschan
2009-09-15  0:27     ` Randy Brukardt

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