* Limited_Controlled and constructor functions @ 2007-01-18 9:51 Maciej Sobczak 2007-01-18 12:13 ` AW: " Grein, Christoph (Fa. ESG) 2007-01-18 16:41 ` Robert A Duff 0 siblings, 2 replies; 10+ messages in thread From: Maciej Sobczak @ 2007-01-18 9:51 UTC (permalink / raw) Hi, Consider another Limited_Controlled problem: -- p.ads: with Ada.Finalization; package P is type T (<>) is private; function Constructor(I : Integer) return T; private type Array_Of_Ints is array (Positive range <>) of Integer; type T (Size : Positive) is new Ada.Finalization.Controlled with record A : Array_Of_Ints(1..Size); end record; end P; -- p.adb: package body P is function Constructor(I : Integer) return T is begin return T'(Ada.Finalization.Controlled with Size => 1, A => (1 => I)); end Constructor; end P; It looks a bit convoluted. :-) The idea is to have a T type that contains the array of integers and a constructor function that creates T with single element in the contained array. T is private, controlled and indefinite, to force the use of constructor function whenever T is declared. Now, I want to make it limited as well by adding limited before private and changing Controlled to Limited_Controlled in two places. I get this when compiling the package: cannot return a local value by reference "Program_Error" will be raised at run time What's going on? -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* AW: Limited_Controlled and constructor functions 2007-01-18 9:51 Limited_Controlled and constructor functions Maciej Sobczak @ 2007-01-18 12:13 ` Grein, Christoph (Fa. ESG) 2007-01-18 16:41 ` Robert A Duff 1 sibling, 0 replies; 10+ messages in thread From: Grein, Christoph (Fa. ESG) @ 2007-01-18 12:13 UTC (permalink / raw) To: comp.lang.ada > Now, I want to make it limited as well by adding limited before private > and changing Controlled to Limited_Controlled in two places. > I get this when compiling the package: > cannot return a local value by reference > "Program_Error" will be raised at run time I think the compiler is not yet full Ada 2005; this should work if I have understood the RM correctly. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-18 9:51 Limited_Controlled and constructor functions Maciej Sobczak 2007-01-18 12:13 ` AW: " Grein, Christoph (Fa. ESG) @ 2007-01-18 16:41 ` Robert A Duff 2007-01-19 7:58 ` Maciej Sobczak 1 sibling, 1 reply; 10+ messages in thread From: Robert A Duff @ 2007-01-18 16:41 UTC (permalink / raw) Maciej Sobczak <no.spam@no.spam.com> writes: > Hi, > > Consider another Limited_Controlled problem: > > -- p.ads: > with Ada.Finalization; > package P is > type T (<>) is private; > function Constructor(I : Integer) return T; > private > type Array_Of_Ints is array (Positive range <>) of Integer; > type T (Size : Positive) is new Ada.Finalization.Controlled with > record > A : Array_Of_Ints(1..Size); > end record; > end P; > > -- p.adb: > package body P is > function Constructor(I : Integer) return T is > begin > return T'(Ada.Finalization.Controlled with > Size => 1, A => (1 => I)); > end Constructor; > end P; > > It looks a bit convoluted. :-) > The idea is to have a T type that contains the array of integers and a > constructor function that creates T with single element in the contained > array. T is private, controlled and indefinite, to force the use of > constructor function whenever T is declared. > > Now, I want to make it limited as well by adding limited before private > and changing Controlled to Limited_Controlled in two places. > I get this when compiling the package: > > cannot return a local value by reference > "Program_Error" will be raised at run time > > What's going on? It works in Ada 2005. It's one of my favorite features of Ada 2005. (By the way, I did part of the work of implementing this in GNAT. The way it works internally is "interesting", because it is important that the above "return" not make a copy; it must build the new object in its final resting place.) Limited types were somewhat broken in Ada 83. We tried to fix them in Ada 95, but the "return by reference" idea was another mistake. That's fixed in Ada 2005. I'm not entirely sure what you're trying to accomplish, since the length of that array can't change, and there's nothing interesting for Finalize to do in this example. Maybe you have other constructors? Anyway, you can do things like this: with Ada.Finalization; package P is type T (Length : Natural; Initial : Integer) is private; function Constructor(I : Integer) return T; private type Array_Of_Ints is array (Positive range <>) of Integer; type T (Length : Natural; Initial : Integer) is new Ada.Finalization.Limited_Controlled with record A : Array_Of_Ints(1..Length) := (others => Initial); end record; end P; My_Object : P.T (Length => 1, Initial => 123); but I'm not sure if that's what you want. The point is, in Ada 95, limited types cannot have constructor functions, which is annoying, but you can often work around the problem by passing information in as discriminants. - Bob ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-18 16:41 ` Robert A Duff @ 2007-01-19 7:58 ` Maciej Sobczak 2007-01-19 9:41 ` Dmitry A. Kazakov 2007-01-20 17:09 ` Gautier 0 siblings, 2 replies; 10+ messages in thread From: Maciej Sobczak @ 2007-01-19 7:58 UTC (permalink / raw) Robert A Duff wrote: > It works in Ada 2005. That's good news. :-) > It's one of my favorite features of Ada 2005. It's one of the many features that are essential for writing robust code, IMHO (from the C++ perspective). > I'm not entirely sure what you're trying to accomplish, since the length > of that array can't change, and there's nothing interesting for Finalize > to do in this example. Maybe you have other constructors? Yes, there are other constructors that accept more parameters and that create longer arrays. What I want to accomplish is the functional way of building lists of values of variant types: P : constant Params := Make_Params(Param("Hello"), Param("Ada"), Param(12), Param(3.14))); Make_Params is a constructor function that creates a list of 4 parameters, each of them being a variant. I wanted to be able to store Strings in the variant without constraining their lengths (which is impossible), so I decided to use access variable that points to unconstrained String. I migh use Unbounded_String as well, but I don't yet see what would be the difference. Everything should be nicely cleaned up after that - that's why Params is controlled, and since I don't want to bother with copy semantics, it is also limited. It is part of the simple database binding that I wanted to write for the sake of exercise. I will make the whole public once it's finished (but I need Ada2005 compiler for that! :-) ). -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-19 7:58 ` Maciej Sobczak @ 2007-01-19 9:41 ` Dmitry A. Kazakov 2007-01-19 13:45 ` Maciej Sobczak 2007-01-20 17:09 ` Gautier 1 sibling, 1 reply; 10+ messages in thread From: Dmitry A. Kazakov @ 2007-01-19 9:41 UTC (permalink / raw) On Fri, 19 Jan 2007 08:58:54 +0100, Maciej Sobczak wrote: > What I want to accomplish is the functional way of building lists of > values of variant types: > > P : constant Params := Make_Params(Param("Hello"), > Param("Ada"), > Param(12), > Param(3.14))); Hmm, but should the parameters and containers of be limited types? I find it rather natural to be able to copy parameter(s), send them over IP... -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-19 9:41 ` Dmitry A. Kazakov @ 2007-01-19 13:45 ` Maciej Sobczak 2007-01-19 14:33 ` Dmitry A. Kazakov 0 siblings, 1 reply; 10+ messages in thread From: Maciej Sobczak @ 2007-01-19 13:45 UTC (permalink / raw) Dmitry A. Kazakov wrote: > On Fri, 19 Jan 2007 08:58:54 +0100, Maciej Sobczak wrote: > >> What I want to accomplish is the functional way of building lists of >> values of variant types: >> >> P : constant Params := Make_Params(Param("Hello"), >> Param("Ada"), >> Param(12), >> Param(3.14))); > > Hmm, but should the parameters and containers of be limited types? Probably not, but... > I find > it rather natural to be able to copy parameter(s) ... I don't like to overengineer things in anticipation of usage patterns that actually might never happen. I prefer to forbid it and wait until it's asked for. I find it easier (well, I at least expected) to forbid copy semantics than to implement it. In C++ it's two lines of code or even half: class MyClass : boost::noncopyable ... ;-) > send them over IP... Then we're talking about serialization. Limited types don't forbid it. -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-19 13:45 ` Maciej Sobczak @ 2007-01-19 14:33 ` Dmitry A. Kazakov 2007-01-22 8:59 ` Maciej Sobczak 0 siblings, 1 reply; 10+ messages in thread From: Dmitry A. Kazakov @ 2007-01-19 14:33 UTC (permalink / raw) On Fri, 19 Jan 2007 14:45:59 +0100, Maciej Sobczak wrote: > Dmitry A. Kazakov wrote: >> On Fri, 19 Jan 2007 08:58:54 +0100, Maciej Sobczak wrote: >> >>> What I want to accomplish is the functional way of building lists of >>> values of variant types: >>> >>> P : constant Params := Make_Params(Param("Hello"), >>> Param("Ada"), >>> Param(12), >>> Param(3.14))); >> >> Hmm, but should the parameters and containers of be limited types? > > Probably not, but... > >> I find it rather natural to be able to copy parameter(s) > > ... I don't like to overengineer things in anticipation of usage > patterns that actually might never happen. I prefer to forbid it and > wait until it's asked for. But you used ":=", which was (no matter what RM says (:-)) a primitive operation undefined for limited types. Prior Ada 2005 it was, now, ":=" in declarations has a different meaning than in statements... > In C++ it's two lines of code or even half: > > class MyClass : boost::noncopyable > ... Huh, C++ has even weaker means to describe formal types contracts. It has dire <class T>. In Ada there is limited, tagged, range <> etc. Far too weak, IMO, but still better than C++. Anyway, there must be a reason why you wanted to have a compound parameters object rather than to specify them directly in the factory function. You didn't say what was the goal. To have an abstract factory? I have a suspicion that it wouldn't work anyway. BTW, you could try streams and getting the object directly from the stream instead. > > send them over IP... > > Then we're talking about serialization. Egh, no, serialization is ordering in time. To be able to copy is about lack of identity and memory-isotropy. > Limited types don't forbid it. Limited types is a kludge. There should be a simpler and clearer way to say that the thingy has no visible compiler-generated copy constructor, no equality, no aggregates, no assignment (in Ada 95). All these are just primitive operations or parts of. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-19 14:33 ` Dmitry A. Kazakov @ 2007-01-22 8:59 ` Maciej Sobczak 0 siblings, 0 replies; 10+ messages in thread From: Maciej Sobczak @ 2007-01-22 8:59 UTC (permalink / raw) Dmitry A. Kazakov wrote: >> In C++ it's two lines of code or even half: >> >> class MyClass : boost::noncopyable >> ... > > Huh, C++ has even weaker means to describe formal types contracts. It has > dire <class T>. In Ada there is limited, tagged, range <> etc. Far too > weak, IMO, but still better than C++. Yes, except that I'm not suprised by what C++ offers with regard to class definitions. I was very surprised by the semantics of Controlled and Limited_Controlled and their funny effects on other parts of my program. >> > send them over IP... >> >> Then we're talking about serialization. > > Egh, no, serialization is ordering in time. You are right. Me too: http://en.wikipedia.org/wiki/Serialization > To be able to copy is about > lack of identity and memory-isotropy. Not really. Memory isotropy (cool technical buzz, btw ;-) ) is about memcpy and memmove. Copy semantics is about what happens when you use relevant language constructs. If memory isotropy is a property of any given type, then copy semantics can be automatically derived. Otherwise it has to be explicitly defined. >> Limited types don't forbid it. > > Limited types is a kludge. A particularly nasty one. > There should be a simpler and clearer way to say > that the thingy has no visible compiler-generated copy constructor, no > equality, no aggregates, no assignment Amen. -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-19 7:58 ` Maciej Sobczak 2007-01-19 9:41 ` Dmitry A. Kazakov @ 2007-01-20 17:09 ` Gautier 2007-01-20 19:39 ` Gautier 1 sibling, 1 reply; 10+ messages in thread From: Gautier @ 2007-01-20 17:09 UTC (permalink / raw) Maciej Sobczak: > What I want to accomplish is the functional way of building lists of > values of variant types: > > P : constant Params := Make_Params(Param("Hello"), > Param("Ada"), > Param(12), > Param(3.14))); Would you be happy with the following ? For the fun, I did it in Ada 83 :-). You can change that with Unbounded_String's and make things nicely, hidden, private, tagged and so on as you like... Note that the function Make_Params was superfluous in that implementation. Output: Parameter # 1: [Hello] Parameter # 2: [Ada] Parameter # 3: [ 12] Parameter # 4: [ 3.14000E+00] --8<-----------8<-----------8<-----------8<-----------8<-----------8<--------- -- start 17:35 -- stop 17:59 pragma Ada_83; with Text_IO, Variant_pkg; procedure Variants is use Variant_pkg; P : constant Params := (Param("Hello"), Param("Ada"), Param(12), Param(3.14)); begin for i in P'Range loop Text_IO.Put_Line( "Parameter #" & Integer'Image(i) & ": [" & Image(P(i).all) & ']' ); end loop; end Variants; --8<-----------8<-----------8<-----------8<-----------8<-----------8<--------- package Variant_pkg is type BorString( maxlength: Positive ) is record length: Natural:= 0; s: String( 1..maxlength ); end record; type Kind is (A_String, An_Integer, A_Float); xamax: constant:= 1024; type Atom(k: Kind) is record case k is when A_String => s: BorString(xamax); when An_Integer => i: Integer; when A_Float => f: Float; end case; end record; type p_Atom is access Atom; type Params is array(Positive range <>) of p_Atom; function Param(s: String) return p_Atom; function Param(i: Integer) return p_Atom; function Param(f: Float) return p_Atom; function Image(a: Atom) return String; end Variant_pkg; --8<-----------8<-----------8<-----------8<-----------8<-----------8<--------- package body Variant_pkg is function Param(s: String) return p_Atom is a: p_Atom:= new Atom(A_String); begin a.s.s(1..s'Length):= s; a.s.length:= s'Length; return a; end Param; function Param(i: Integer) return p_Atom is a: p_Atom:= new Atom(An_Integer); begin a.i:= i; return a; end Param; function Param(f: Float) return p_Atom is a: p_Atom:= new Atom(A_Float); begin a.f:= f; return a; end Param; function Image(a: Atom) return String is begin case a.k is when A_String => return a.s.s(1..a.s.length); when An_Integer => return Integer'Image(a.i); when A_Float => return Float'Image(a.f); end case; end Image; end Variant_pkg; ______________________________________________________________ Gautier -- http://www.mysunrise.ch/users/gdm/index.htm Ada programming -- http://www.mysunrise.ch/users/gdm/gsoft.htm NB: For a direct answer, e-mail address on the Web site! ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Limited_Controlled and constructor functions 2007-01-20 17:09 ` Gautier @ 2007-01-20 19:39 ` Gautier 0 siblings, 0 replies; 10+ messages in thread From: Gautier @ 2007-01-20 19:39 UTC (permalink / raw) Oh, and a version without implicit dynamic allocation at all: --8<-----------8<-----------8<-----------8<-----------8<-----------8<--------- pragma Ada_83; with Text_IO, Variant_pkg; procedure Variants is use Variant_pkg; P : constant Params := (Param("Hello"), Param("Ada"), Param(12), Param(3.14)); begin for i in P'Range loop Text_IO.Put_Line( "Parameter #" & Integer'Image(i) & ": [" & Image(P(i)) & ']' ); end loop; end Variants; --8<-----------8<-----------8<-----------8<-----------8<-----------8<--------- package Variant_pkg is type BorString( maxlength: Positive ) is record length: Natural:= 0; s: String( 1..maxlength ); end record; type Kind is (A_String, An_Integer, A_Float); xamax: constant:= 1024; type Atom(k: Kind:= An_Integer) is record case k is when A_String => s: BorString(xamax); when An_Integer => i: Integer; when A_Float => f: Float; end case; end record; type Params is array(Positive range <>) of Atom; function Param(s: String) return Atom; function Param(i: Integer) return Atom; function Param(f: Float) return Atom; function Image(a: Atom) return String; end Variant_pkg; --8<-----------8<-----------8<-----------8<-----------8<-----------8<--------- package body Variant_pkg is function Param(s: String) return Atom is a: Atom(A_String); begin a.s.s(1..s'Length):= s; a.s.length:= s'Length; return a; end Param; function Param(i: Integer) return Atom is begin return Atom'(k => An_Integer, i => i); end Param; function Param(f: Float) return Atom is begin return Atom'(k => A_Float, f => f); end Param; function Image(a: Atom) return String is begin case a.k is when A_String => return a.s.s(1..a.s.length); when An_Integer => return Integer'Image(a.i); when A_Float => return Float'Image(a.f); end case; end Image; end Variant_pkg; ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-01-22 8:59 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-01-18 9:51 Limited_Controlled and constructor functions Maciej Sobczak 2007-01-18 12:13 ` AW: " Grein, Christoph (Fa. ESG) 2007-01-18 16:41 ` Robert A Duff 2007-01-19 7:58 ` Maciej Sobczak 2007-01-19 9:41 ` Dmitry A. Kazakov 2007-01-19 13:45 ` Maciej Sobczak 2007-01-19 14:33 ` Dmitry A. Kazakov 2007-01-22 8:59 ` Maciej Sobczak 2007-01-20 17:09 ` Gautier 2007-01-20 19:39 ` Gautier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox