* 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 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-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-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