|
From: Florian Weimer on 1 Sep 2005 11:54 * Georg Bauhaus: > Florian Weimer wrote: > >> Even more problematic is the empty array whose index type >> is an enumeration type with just one enumeration literal. > > This looks like a formalist's problem to me. To some extent, sure. Furtunately, these arrays do not occur in practice. However, you have to think about this problem for a moment when you write generic containers.
From: Robert A Duff on 1 Sep 2005 11:57 "Gene" <gene.ressler(a)gmail.com> writes: > Seldom am I surprised by Ada semantics, but today they got me. > > type Int_List_Type is array(Integer range <>) of Integer; "Positive range <>" or "Natural range <>" is probably a better idea. If you have an unconstrained array such that Index_Type'First = Index_Type'Base'First, you will run into trouble with empty arrays. > return F(a(1..i - 1) & a(i + 1, a'Last)); > The gotcha is that when (and only when) i is determined to be zero, the > concatenation in the recursive call to F produces a starting index of 2 > rather than 1. Of course this causes the base case test to raise an > exception in the next recursive call. This is in accordance with the > ALRM and GNAT implements it perfectly. Consider: X: String(-99 .. -10_000); -- empty string Y: constant String := X & "Hello world." Ada requires the bounds of a String to be in Positive, EXCEPT when it's an empty String. So X'First = -99, but Y'First can't be -99. Your suggestion would make sense if Ada didn't allow weird things like String(-99 .. -10_000). It shouldn't -- allowing such things just causes confusion and bugs. The rule should be that 'First of every String is exactly 1. The 'Last should be in Positive, except in the empty string case, where the bounds should be exactly 1..0. The syntax for declaring String could be: type String(Length: Natural) is array (Positive range 1..Length) of Character; No need for the "range <>" syntax in this language! There's also an efficiency advantage: the dope can be just one word instead of two, and the code to calculate 'Length could be branch free. Note that Ada 200X has a Vectors generic container package, which implements growable arrays. If you pass in Integer as the index type, you will get Constraint_Error at instantiation time, for this very reason. For the same reason, you can't pass an enumeration or modular type as the index type -- empty vectors wouldn't work. > Yes I know how to recode this to use a'First instead of 1 as needed. > > Nonetheless the rule seems silly: When a leading zero-length array is > catenated to another array the result takes on the starting index of > the _second_ operand. This doesn't make sense to me. Why not use the > starting index of the zero-length array? - Bob
From: Robert A Duff on 1 Sep 2005 12:04 "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> writes: > On 31 Aug 2005 20:16:43 -0700, Gene wrote: > > > Nonetheless the rule seems silly: When a leading zero-length array is > > catenated to another array the result takes on the starting index of > > the _second_ operand. This doesn't make sense to me. Why not use the > > starting index of the zero-length array? > > Because that might be ill-defined, I guess. > > A more interesting question is why Empty'First does not raise any > exception. Heh? You want this: procedure Put(S: String) is begin for I in S'First..S'Last loop -- equivalent to S'Range Put_Char(S(I)); to crash when S = ""? >... After all, there is no any lower bound of an empty index range. In Ada, every range, and every array, has both a lower and an upper bound. > Provided, that empty arrays are all same, of course. Depends on what you mean by "same". ;-) Different empty arrays can have different bounds -- but "=" returns True! >... If not, then another > interesting question would appear: how to make an empty array with the > lower bound Integer'First? You can't. You should always make sure Index'First > Index'Base'First when using the "Index range <>" syntax. (But you don't need to do that when you have a constrained array -- "...array(Index) of ...".) - Bob
From: Robert A Duff on 1 Sep 2005 12:09 Florian Weimer <fw(a)deneb.enyo.de> writes: > * Dmitry A. Kazakov: > > > A more interesting question is why Empty'First does not raise any > > exception. After all, there is no any lower bound of an empty index range. > > Provided, that empty arrays are all same, of course. If not, then another > > interesting question would appear: how to make an empty array with the > > lower bound Integer'First? > > You can't. Even more problematic is the empty array whose index type > is an enumeration type with just one enumeration literal. Why would you want an unconstrained array indexed by enumeration type? And why would you want an empty array if the array type is constrained? As for modular types -- well, they're an abomination all around. It makes no sense whatsoever to have an index type for an unconstrained array such that Index'Pred(Index'First) > Index'First! - Bob
From: Dmitry A. Kazakov on 1 Sep 2005 14:06
On 01 Sep 2005 12:04:17 -0400, Robert A Duff wrote: > "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> writes: > >> On 31 Aug 2005 20:16:43 -0700, Gene wrote: >> >>> Nonetheless the rule seems silly: When a leading zero-length array is >>> catenated to another array the result takes on the starting index of >>> the _second_ operand. This doesn't make sense to me. Why not use the >>> starting index of the zero-length array? >> >> Because that might be ill-defined, I guess. >> >> A more interesting question is why Empty'First does not raise any >> exception. > > Heh? You want this: > > procedure Put(S: String) is > begin > for I in S'First..S'Last loop -- equivalent to S'Range > Put_Char(S(I)); > > to crash when S = ""? Yes. It is in my view no different from Y := X / X; crashing when X=0. The former should be for I in S'Range loop -- is not equivalent to S'First..S'Last when S is "" The latter should be: Y := 1; -- is not equivalent to X / X when X is 0 >>... After all, there is no any lower bound of an empty index range. > > In Ada, every range, and every array, has both a lower and an upper > bound. That's exactly the problem! (:-)) >> Provided, that empty arrays are all same, of course. > > Depends on what you mean by "same". ;-) Different empty arrays can > have different bounds -- but "=" returns True! Ditto. Empty sets are indistinguishable. They have no identity. Ada's empty arrays are different with all nasty consequences of that. >>... If not, then another >> interesting question would appear: how to make an empty array with the >> lower bound Integer'First? > > You can't. Which is bad. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de |