!standard A.18(0/2) 05-10-24 AC95-00120/01 !class Amendment 05-10-24 !status received no action 05-10-24 !status received 05-10-02 !subject Extending a primitive routine !appendix From: Martin Dowie Date: Sunday, Octoher 2, 2005 1:12 PM I didn't realize that changes were still being proposed/allowed at this stage until Randy sent in the "extends" email. :-) I have a suggestion that I hope will be fairly simple and hopefully useful... I think that we could extend the Ada.Containers.* hierarchy to include "Bounded_" variants of each container type by defining that each bounded package has exactly the same specification as the unbounded version, except that the container type has a "(Max_Length : Count_Type)" constraint. Insert/Append routines would raise a Constraint_Error if "Length (Container) = Max_Length" (or, a "Length_Error : exception;" could be added to Ada.Containers). The only 'tricky' bit is what to with: 1) procedure Set_Length Either check and raise exception or limit to Max_Length even if "Length > Container.Max_Length"? 2) each function "&" => a) if Left or Right is the only container then simply check for space; b) if Left and Right are elements then return a Max_Length => 2 container; c) if Left and Right are containers then append as much of Right to a new container with Max_Length of Left.Max_Length. Alternatively for "&" they could return a new container of Left.Max_Length + Right.Max_Length but that seems against the nature of bounded things and not so much in keeping with bounded strings. I'm not too fussed about what the 'actual' rules are/would be, I'm just pointing out that these are the only things that would need any discussion. Anyway, I hope I've shown that it would be /simple/ to double the size of the Ada.Container.* hierarchy with very little effort (and by effort, I mean 'text'! :-), in much the same way as "Wide_" packages are added to the RM. I have a sample "Ada.Containers.Bounded_Vectors" if anyone would like to see such a beast. p.s. My $0.02 would choose "check&raise" for what to do with Set_Length/"&" subprograms, by the way ;-) **************************************************************** From: Bob Duff Date: Sunday, October 2, 2005 8:33 PM > I didn't realize that changes were still being proposed/allowed at this > stage until Randy sent in the "extends" email. :-) I think Randy's suggestion was for Ada 201X, not Ada 2005. ;-) > I have a suggestion that I hope will be fairly simple and hopefully > useful... > > I think that we could extend the Ada.Containers.* hierarchy to include > "Bounded_" variants of each container type by defining that each bounded > package has exactly the same specification as the unbounded version, > except that the container type has a "(Max_Length : Count_Type)" constraint. Hmm... If I say: X: Bounded_Whatever(Max_Length => 80); ... X := Y & Z; where Length(Y) + Length(Z) <= 80, I would like it to work. I don't know how to do that in Ada. **************************************************************** From: Jeffrey Carter Date: Sunday, October 2, 2005 10:04 PM > I think that we could extend the Ada.Containers.* hierarchy to include > "Bounded_" variants of each container type by defining that each bounded > package has exactly the same specification as the unbounded version, > except that the container type has a "(Max_Length : Count_Type)" > constraint. This doesn't work very well, because user-defined assignment doesn't handle this kind of thing. That's why bounded strings have the limit as a generic formal constant, not a discriminant on Bounded_String. Somehow, I doubt anything is being considered for Ada 0X anymore. Randy said his suggestion was for Ada 1X. **************************************************************** From: Matthew Heaney Date: Monday, October 3, 2005 9:05 AM > I think that we could extend the Ada.Containers.* hierarchy to include > "Bounded_" variants of each container type by defining that each bounded > package has exactly the same specification as the unbounded version, > except that the container type has a "(Max_Length : Count_Type)" > constraint. The container type would have to be limited, because of assignment behavior. What you refer to as Max_Length above is really just capacity. > 1) procedure Set_Length > Either check and raise exception or limit to Max_Length even > if "Length > Container.Max_Length"? Just raise CE. > 2) each function "&" => > a) if Left or Right is the only container then simply check for space; > b) if Left and Right are elements then return a Max_Length => 2 > container; > c) if Left and Right are containers then append as much of Right to a > new container with Max_Length of Left.Max_Length. No. Operator "&" is gone, because the type has to be limited. **************************************************************** From: Martin Dowie Date: Monday, October 3, 2005 10:17 AM I could live with either "Max_Length" or "Capacity". Why would "&" have to go? They are present in "Bounded_String"-s... Can you give me an example of the problems with assignment behaviour? Because just now I'm sitting in front of something that seems to work fine with everything I try and throw at it. **************************************************************** From: Matthew Heaney Date: Monday, October 3, 2005 10:30 AM > Why would "&" have to go? They are present in "Bounded_String"-s... Because there's nothing you can to do with the result, if the type is limited. Actually, I should take that back. Operator "&" could become a constructor-type function (aka "initializer"), since you would only be able to use it during the declaration of the bounded contained object (because the type is limited). > Can you give me an example of the problems with assignment behaviour? > Because just now I'm sitting in front of something that seems to work > fine with everything I try and throw at it. Assuming the type were non-limited: declare C1 : CT (42); C2 : CT (1963); begin C2 := C1; -- raises CE end; (But maybe there were some changes in semantics for Ada 2005, such that the assignment no longer raises CE.) **************************************************************** From: Matthew Heaney Date: Monday, October 3, 2005 11:29 AM > Hmm... If I say: > > X: Bounded_Whatever(Max_Length => 80); > ... > X := Y & Z; > > where Length(Y) + Length(Z) <= 80, I would like it to work. > I don't know how to do that in Ada. Hmmm... Why not? If the discriminant of the result of Y & Z is the same as X, then the assignment will succeed. And the sum of the lengths can be calculated in the implementation of "&". Another issue wrt assignment of bounded forms is the (in)efficiency, since there will be a bitwise copy of both the active and inactive ("free store") elements. Martin: the Charles library has bounded list forms (having a clever implementation of the free store, IMHO). You can play around with those if you want to get some more data... **************************************************************** From: Martin Dowie Date: Monday, October 3, 2005 11:50 AM Thanks Matt - I'll take a look - is there an easy 'zipped' version of the head, or do I need to download each file individually? (I've never really used CVS) And while I can't do: declare C1 : CT (42); C2 : CT (1963); begin C2 := C1; -- raises CE end; I can do: declare C1 : CT (42); C2 : CT (1963); begin C2 := C2 & C1; -- works fine end; **************************************************************** From: Bob Duff Date: Monday, October 3, 2005 12:26 PM > Hmmm... Why not? If the discriminant of the result of Y & Z is the same > as X, then the assignment will succeed. And the sum of the lengths can > be calculated in the implementation of "&". I was thinking of this: type Bounded_Sequence(Max_Length: Natural) is record Elements: Element_Array(1..Max_Length); Length: Natural := 0; end record; X: Bounded_Sequence(Max_Length => 80); Y: Bounded_Sequence(Max_Length => 40); ... Now, if Y.Length = 20, I would like to be able to say "X := Y", since the length of Y is shorter than the Max_Length of X. But that doesn't work. Same issue for "X := Y & Z" -- the "&" operation can calculate the right length for the result, but it can't calculate the right Max_Length. As you pointed out in another message, this is why Bounded_Strings is generic on the max length. That means all objects of a given type will have the same max length, thus trivially ensuring that, as you said above, the max length "of the result of Y & Z is the same as X". > Another issue wrt assignment of bounded forms is the (in)efficiency, > since there will be a bitwise copy of both the active and inactive > ("free store") elements. Good point. Of course that doesn't matter if the thing is limited, and if it's limited, the issues about assignment and "&" go away. In Ada 2005, limited is one good way to go. In any case, it's not _trivial_ to add these bounded versions, nor to decide on their exact semantics. So I think it's unlikely that they will be included in Ada 2005. Go for 2015! **************************************************************** From: Martin Dowie Date: Monday, October 3, 2005 11:26 PM >I think Randy's suggestion was for Ada 201X, not Ada 2005. ;-) > > Apologies for being a bit early with my Ada1Z proposal then! :-) >Hmm... If I say: > > X: Bounded_Whatever(Max_Length => 80); > ... > X := Y & Z; > >where Length(Y) + Length(Z) <= 80, I would like it to work. >I don't know how to do that in Ada. > Ok, I'm confused by this one as my implementation seems to do the right thing for this!... Anyway, I guess all this can wait for the ISO IWA. -- bounded_integer_vectors.ads with Ada.Containers.Bounded_Vectors; package Bounded_Integer_Vectors is new Ada.Containers.Bounded_Vectors (Natural, Integer); -- test_biv.adb with Ada.Containers; use Ada.Containers; with Ada.Exceptions; use Ada.Exceptions; with Ada.Text_IO; use Ada.Text_IO; with Bounded_Integer_Vectors; use Bounded_Integer_Vectors; procedure Test_BIV is subtype Vector_3 is Vector (3); V1, V2, V3 : Vector_3; begin Put_Line ("Length =>" & Count_Type'Image (V1.Length)); V1.Append (1); Put_Line ("Length =>" & Count_Type'Image (V1.Length)); V1.Append (3); Put_Line ("Length =>" & Count_Type'Image (V1.Length)); V1.Append (6); Put_Line ("Length =>" & Count_Type'Image (V1.Length)); begin V1.Append (10); exception when Error : others => Put_Line ("!!! " & Exception_Message (Error)); end; Put_Line ("Length =>" & Count_Type'Image (V1.Length)); Put_Line ("Length =>" & Count_Type'Image (V3.Length)); V3 := V1 & V2; Put_Line ("Length =>" & Count_Type'Image (V3.Length)); end Test_BIV; -- result.txt C:\Ada\Bounded_Containers\gps\obj\test_biv.exe Length => 0 Length => 1 Length => 2 Length => 3 !!! Insert error, already full. Length => 3 Length => 0 Length => 3 **************************************************************** From: Bob Duff Date: Tuesday, October 4, 2005 12:01 PM > Ok, I'm confused by this one as my implementation seems to do the right > thing for this!... > subtype Vector_3 is Vector (3); > V1, V2, V3 : Vector_3; Try it like this: V1, V2: Vector_3; V3: Vector(6); 6 is plenty big enough to store 3 characters, but the assignment will raise Constraint_Error. **************************************************************** From: Martin Dowie Date: Tuesday, October 4, 2005 12:32 PM Well, that depends on what I make "&" mean! :-) declare C1, C2 : Bounded_Integer_Vectors.Vector (3); C3 : Bounded_Integer_Vectors.Vector (6); begin C1.Append (1); C1.Append (3); C1.Append (7); C2.Append (11); C2.Append (13); C2.Append (17); C3 := C1 & C2; Put_Line ("+++ No exception raised"); Put_Line ("Length =>" & Count_Type'Image (C3.Length)); exception when Error : others => Put_Line ("!!! " & Exception_Message (Error)); end; -- results.txt +++ No exception raised Length => 6 **************************************************************** From: Jeffrey Carter Date: Tuesday, October 4, 2005 1:00 PM > Well, that depends on what I make "&" mean! :-) Sure, but the point is that there's no way to make A := B & C; work for any A, B, & C such that Length (B) + Length (C) <= A.Max_Length. Indeed, if you can make it work for your example and for A : Vector ( 7); B : Vector (10); C : Vector (23); Length (B) = 3 Length (C) = 3 I'll be impressed. I suspect this discussion should be moved from Ada-Comment. ****************************************************************