* access to controlled types @ 1999-02-03 0:00 Terry J. Westley 1999-02-04 0:00 ` Stephen Leake ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: Terry J. Westley @ 1999-02-03 0:00 UTC (permalink / raw) In a new version of TASH, I've implmented an interface to Tcl objects (which are reference counted) with Ada controlled types. I've been very impressed with how well this works in GNAT. But, there are certain calls in the interface which return an access to a class-wide type. It's easy to reference count these newly created objects, but since the access type is not controlled, the reference counts don't get decremented. What's the solution? Should I declare another controlled type which *contains* an access to the original controlled type? Or, is there a better solution? -- Terry J. Westley, Principal Engineer Veridian Engineering, Calspan Operations twestley@buffalo.veridian.com http://www.veridian.com/ ------------------------------------------------------- Author of TASH, an Ada binding to Tcl/Tk. Visit the TASH web site at http://tash.calspan.com. ------------------------------------------------------- ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: access to controlled types 1999-02-03 0:00 access to controlled types Terry J. Westley @ 1999-02-04 0:00 ` Stephen Leake 1999-02-05 0:00 ` Terry J. Westley 1999-02-04 0:00 ` news.oxy.com 1999-03-01 0:00 ` access to controlled types Matthew Heaney 2 siblings, 1 reply; 8+ messages in thread From: Stephen Leake @ 1999-02-04 0:00 UTC (permalink / raw) "Terry J. Westley" <twestley@buffalo.veridian.com> writes: > In a new version of TASH, I've implmented an interface > to Tcl objects (which are reference counted) with Ada > controlled types. I've been very impressed with how > well this works in GNAT. > > But, there are certain calls in the interface which > return an access to a class-wide type. It's easy to > reference count these newly created objects, but since > the access type is not controlled, the reference counts > don't get decremented. What's the solution? Should I > declare another controlled type which *contains* an > access to the original controlled type? Or, is there > a better solution? Perhaps the functions that return a class-wide access type should simply be removed. Do they serve a real purpose in the system? Is there another (safer) way to satisfy that need? I guess the latter is what you are suggesting. But often, a function that violates an abstraction truly does not belong. -- Stephe ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: access to controlled types 1999-02-04 0:00 ` Stephen Leake @ 1999-02-05 0:00 ` Terry J. Westley 1999-02-20 0:00 ` Matthew Heaney 0 siblings, 1 reply; 8+ messages in thread From: Terry J. Westley @ 1999-02-05 0:00 UTC (permalink / raw) >"Terry J. Westley" <twestley@buffalo.veridian.com> writes: > >> In a new version of TASH, I've implmented an interface >> to Tcl objects (which are reference counted) with Ada >> controlled types. I've been very impressed with how >> well this works in GNAT. >> >> But, there are certain calls in the interface which >> return an access to a class-wide type. It's easy to >> reference count these newly created objects, but since >> the access type is not controlled, the reference counts >> don't get decremented. What's the solution? Should I >> declare another controlled type which *contains* an >> access to the original controlled type? Or, is there >> a better solution? > Stephen Leake <Stephen.Leake@gsfc.nasa.gov> responds: >Perhaps the functions that return a class-wide access type should >simply be removed. Do they serve a real purpose in the system? Is >there another (safer) way to satisfy that need? I guess the latter is >what you are suggesting. But often, a function that violates an >abstraction truly does not belong. You have a good point. I'll think about it a bit. The specific situation is that TASH supports Tcl lists which are heterogenous. So, when you fetch an element out of the list, it could be an integer, a float, a string, or another list. Other functions that return an element of the list are Head and Tail. -- Terry J. Westley, Principal Engineer Veridian Engineering, Calspan Operations twestley@buffalo.veridian.com http://www.veridian.com/ ------------------------------------------------------- Author of TASH, an Ada binding to Tcl/Tk. Visit the TASH web site at http://tash.calspan.com. ------------------------------------------------------- ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: access to controlled types 1999-02-05 0:00 ` Terry J. Westley @ 1999-02-20 0:00 ` Matthew Heaney 1999-02-20 0:00 ` Matthew Heaney 0 siblings, 1 reply; 8+ messages in thread From: Matthew Heaney @ 1999-02-20 0:00 UTC (permalink / raw) "Terry J. Westley" <twestley@buffalo.veridian.com> writes: > You have a good point. I'll think about it a bit. The specific > situation is that TASH supports Tcl lists which are heterogenous. > > So, when you fetch an element out of the list, it could be an > integer, a float, a string, or another list. Can your list return a discriminated object? Something like the code below. I don't think you need to return a tagged type object here, because your interest is in an object (the item in the list), not in operations of a type. The items in your list are heterogenous, but they are all not part of the same type hierarchy: floats and integers and strings and lists are all different classes of types. That means you need a variant record, not a tagged type. To use this list, you'd do like this: declare Item : constant List_Item := Get_Head (List); begin case Get_Item_Kind (Item) is when Float_List_Item => declare F : constant Float := Get_Float_Item (Item); begin <do something with F> end; when Integer_List_Item => ... end; with Ada.Finalization; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; package Lists is type List_Type is private; type List_Item (<>) is private; function Get_Head (List : List_Type) return List_Item; -- other list ops here type List_Item_Kind is (Float_List_Item, Integer_List_Item, String_List_Item, List_List_Item); function Get_Item_Kind (Item : List_Item) return List_Item_Kind; function Get_Float_Item (Item : List_Item) return Float; -- gets for other kinds here private type Node_Type; type Node_Access is access Node_Type; type List_Type is new Ada.Finalization.Controlled with record Head : Node_Access; end record; procedure Adjust (List : in out List_Type); procedure Finalize (List : in out List_Type); type List_Item (Kind : List_Item_Kind := List_Item_Kind'First) is record case Kind is when Float_List_Item => F : Float; when Integer_List_Item => I : Integer; when String_List_Item => S : Unbounded_String; when List_List_Item => L : List_Type; end case; end record; end Lists; package body Lists is type Node_Type is record Item : List_Item; Ref_Count : Natural := 0; Next : List_Type; -- or Node_Access? end record; function Get_Head (List : List_Type) return List_Item is begin return List.Head.Item; end; function Get_Item_Kind (Item : List_Item) return List_Item_Kind is begin return Item.Kind; end; function Get_Float_Item (Item : List_Item) return Float is begin return Item.F; end; procedure Adjust (List : in out List_Type) is begin null; -- adjust ref count end; procedure Finalize (List : in out List_Type) is begin null; -- adjust ref count end; end Lists; ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: access to controlled types 1999-02-20 0:00 ` Matthew Heaney @ 1999-02-20 0:00 ` Matthew Heaney 0 siblings, 0 replies; 8+ messages in thread From: Matthew Heaney @ 1999-02-20 0:00 UTC (permalink / raw) Matthew Heaney <matthew_heaney@acm.org> writes: > "Terry J. Westley" <twestley@buffalo.veridian.com> writes: > > > You have a good point. I'll think about it a bit. The specific > > situation is that TASH supports Tcl lists which are heterogenous. > > > > So, when you fetch an element out of the list, it could be an > > integer, a float, a string, or another list. > > > Can your list return a discriminated object? Something like the code > below. Actually, I thought of another way to do this, that doesn't require a List_Item type in the spec. Function Get_Head can just return the different types (float, integer, string, list) directly, without the intermediate type. If you know you have just floats, say, then you don't even have to bother calling the Get_Item_Kind query function. I don't really know if this is what you had in mind. But if you want a reference-counted list, then a private non-limited list type, implemented as deriving from Controlled, is the way to go. This is one example of the fact that you do not have to expose access types in the spec. Access types are only for implementing abstractions, and can thus be hidden from clients. (There is one exception to this rule. See my post about the Interpreter pattern in the patterns archive at the ACM, which uses an access type as a "handle," to point to a limited and indefinite type.) with Ada.Finalization; package Lists2 is type List_Type is private; type List_Item_Kind is (Float_List_Item, Integer_List_Item, String_List_Item, List_List_Item); function Get_Item_Kind (List : List_Type) return List_Item_Kind; function Get_Head (List : List_Type) return Float; function Get_Head (List : List_Type) return Integer; function Get_Head (List : List_Type) return String; function Get_Head (List : List_Type) return List_Type; private type Node_Type; type Node_Access is access Node_Type; type List_Type is new Ada.Finalization.Controlled with record Head : Node_Access; end record; procedure Adjust (List : in out List_Type); procedure Finalize (List : in out List_Type); end Lists2; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; package body Lists2 is type List_Item (Kind : List_Item_Kind := List_Item_Kind'First) is record case Kind is when Float_List_Item => F : Float; when Integer_List_Item => I : Integer; when String_List_Item => S : Unbounded_String; when List_List_Item => L : List_Type; end case; end record; type Node_Type is record Item : List_Item; Ref_Count : Natural := 0; Next : List_Type; -- or Node_Access? end record; function Get_Item_Kind (List : List_Type) return List_Item_Kind is begin return List.Head.Item.Kind; end; function Get_Head (List : List_Type) return Float is begin return List.Head.Item.F; end; function Get_Head (List : List_Type) return Integer is begin return List.Head.Item.I; end; function Get_Head (List : List_Type) return String is begin return To_String (List.Head.Item.S); end; function Get_Head (List : List_Type) return List_Type is begin return List.Head.Item.L; end; procedure Adjust (List : in out List_Type) is begin null; -- adjust ref count end; procedure Finalize (List : in out List_Type) is begin null; -- adjust ref count end; end Lists2; ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: access to controlled types 1999-02-03 0:00 access to controlled types Terry J. Westley 1999-02-04 0:00 ` Stephen Leake @ 1999-02-04 0:00 ` news.oxy.com 1999-02-05 0:00 ` Garb Coll + Heap Cmpctn (was:access to controlled types) Nick Roberts 1999-03-01 0:00 ` access to controlled types Matthew Heaney 2 siblings, 1 reply; 8+ messages in thread From: news.oxy.com @ 1999-02-04 0:00 UTC (permalink / raw) Terry J. Westley wrote in message <918079635.219550@outpost1.roc.accglobal.net>... > >But, there are certain calls in the interface which >return an access to a class-wide type. It's easy to >reference count these newly created objects, but since >the access type is not controlled, the reference counts >don't get decremented. What's the solution? Should I >declare another controlled type which *contains* an >access to the original controlled type? Or, is there >a better solution? I think this is one of the best solutions. I did exactly the same some time ago when I was playing with controlled types aiming at creating some type of universal class-wide communication objects (controlled types) that could work in conjunction with access types to them and all that together should perform automatic garbage collection. The problem with the simple access types to the controlled types was that they do not resolve the problem of deleting controlled types when there is no more references to the last ones. Controlled types are only deleted on leaving their life scope. Object lifetime scope can be reduced by using internal/local blocks but in many cases this is not an optimal solution. To resolve that I created and tested small top-level package that performs user defined garbage collection using controlled access type to the controlled class-wide types. This package (just small experiment or exercise) proved to be working fine and I an going to use it later to create hierarchy of controlled types with automatic garbage collection. Just few days ago I remembered one of the questions that was asked somewhere some time ago (I do not remember where). The problem was how to distinguish statically created objects at compile time from the dynamically created objects during run time. This is very important in conjunction with controlled types as any attempt to free up static object will raise run-time error. Only dynamically created objects may be deleted. As I understand this issue is not addressed in the LRM (but may be I am wrong and someone will correct me), so I invented some kind of solution to resolve this issue an I am going to test it as well when I add that changes in my package. If that solution (it is extremely simple) would be used by the compiler itself then life would be much more easier. Another issue is that sometimes it is necessary to postpone deleting of the object in order not to affect performance of your code. This also can be easily resolved by creating separate garbage collection process that performs the delayed deleting of your object. During finalization (if the object should be deleted) you just pass reference to your controlled object to that garbage collection process and that's it. That garbage collection process can be any structure (list, tree e.t.c.) containing controlled access type to class-wide controlled types and set of needed operations on that structure to perform controlled finalization of the objects within that structure. I should mention that I am not a programmer. I am telecommunications engineer so I am playing with Ada occasionally. Also I never read anything about how garbage collection is implemented in any other system. What I was describing was just my own approach to that problem using Ada facilities. May be there is something wrong in what I am doing. May be there exist better solutions. As a matter of fact garbage collection issues have somewhat increased significance now and maybe it is worth to discuss it in separate discussion thread. I have some topics for that discussion Regards, Vladimir Olensky (vladimir_olensky@yahoo.com) (Vladimir_Olensky@oxy.com) Telecommunication specialist, Occidental C.I.S. Service, Inc. ( www.oxy.com ) Moscow, Russia. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Garb Coll + Heap Cmpctn (was:access to controlled types) 1999-02-04 0:00 ` news.oxy.com @ 1999-02-05 0:00 ` Nick Roberts 0 siblings, 0 replies; 8+ messages in thread From: Nick Roberts @ 1999-02-05 0:00 UTC (permalink / raw) news.oxy.com wrote in message <79bjn8$5ao$1@remarQ.com>... [...] |As a matter of fact garbage collection issues have somewhat increased |significance now and maybe it is worth to discuss it in separate discussion |thread. I have some topics for that discussion By all means. (See also: separate thread). ------------------------------------------- Nick Roberts ------------------------------------------- ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: access to controlled types 1999-02-03 0:00 access to controlled types Terry J. Westley 1999-02-04 0:00 ` Stephen Leake 1999-02-04 0:00 ` news.oxy.com @ 1999-03-01 0:00 ` Matthew Heaney 2 siblings, 0 replies; 8+ messages in thread From: Matthew Heaney @ 1999-03-01 0:00 UTC (permalink / raw) Look for my recent post about "smart pointers" in the ACM patterns archive. I show a technique that answers your question. "Terry J. Westley" <twestley@buffalo.veridian.com> writes: > In a new version of TASH, I've implmented an interface > to Tcl objects (which are reference counted) with Ada > controlled types. I've been very impressed with how > well this works in GNAT. > > But, there are certain calls in the interface which > return an access to a class-wide type. It's easy to > reference count these newly created objects, but since > the access type is not controlled, the reference counts > don't get decremented. What's the solution? Should I > declare another controlled type which *contains* an > access to the original controlled type? Or, is there > a better solution? ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~1999-03-01 0:00 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1999-02-03 0:00 access to controlled types Terry J. Westley 1999-02-04 0:00 ` Stephen Leake 1999-02-05 0:00 ` Terry J. Westley 1999-02-20 0:00 ` Matthew Heaney 1999-02-20 0:00 ` Matthew Heaney 1999-02-04 0:00 ` news.oxy.com 1999-02-05 0:00 ` Garb Coll + Heap Cmpctn (was:access to controlled types) Nick Roberts 1999-03-01 0:00 ` access to controlled types Matthew Heaney
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox