Re: Surprise in array concatenation
- From: Robert A Duff <bobduff@xxxxxxxxxxxxxxxxxxxx>
- Date: 06 Sep 2005 11:30:07 -0400
"Bob Spooner" <rls19@xxxxxxx> writes:
> "Robert A Duff" <bobduff@xxxxxxxxxxxxxxxxxxxx> wrote in message
> news:wccoe77nq3l.fsf@xxxxxxxxxxxxxxxxxxxxxxx
> > tmoran@xxxxxxx writes:
> >
> snip...
> >
> > Slices should slide to the lower bound. The Ada rule breaks
> > abstraction:
>
> So if I pass a subprogram a slice of an array indexed by an enumeration type
> then the mapping of the values to the enumeration type should change?
No. Let me explain more clearly what I meant:
In Ada, for a given array type, you can choose to fix both bounds, or
neither. You cannot choose to fix the lower bound (for all objects of
the type), but not the upper bound. I think the programmer should have
all four choices of fixing the bounds for an array type.
Part of the problem here is that "array" is a fairly low-level
abstraction. When the index is an enumeration type, you're usually
using the array to represent a higher-level concept -- a "mapping" from
enum values to whatever. When you declare something like String, on the
other hand, you're using the array to represent a different higher-level
concept -- a "sequence of characters".
"Sequence" and "mapping" are different (though related) concepts.
For a sequence, the indices have no inherent meaning -- they just
represent the order in which the elements appear in the sequence.
So I don't have trouble with the idea that slices of strings should
slide the bounds to 1..Length, whereas slices of a "mapping" sort of
array should not.
> >
> > procedure P(X: String) is
> > begin
> > ...
> > end P;
> >
> > Y: String := "Hello, world!";
> >
> > P(Y(3..4));
> >
> > Inside the body of P, X is just a String -- we don't (or shouldn't) know
> > that it's a substring of Y. So we can't possibly make any sense (inside
> > P) of the fact that X'First = 3. Index 3 from what?
> >
> > If I ran the circus, X'First would be 1.
> >
>
> But that would make String a special case of an array if you allow other
> arrays to start with a value other than the first value of the index type.
> Yet another thing we would have to remember...
Yes, you have to remember, for each array type, whether the programmer
who wrote it intended it as a sequence or a mapping. If a sequence, you
have to remember whether they fixed the lower bound at zero or one (or
they did some other weird thing, presumably for good reason).
> >
> > I wouldn't insist on starting _all_ arrays at 1, but I think it makes
> > sense for _many_ arrays, including String.
> >
>
> Many other special cases to remember as well?
Yes, String is just one example where it makes sense to fix the lower
bound at 1. Just like for a linked list, you have to remember whether
it's circular or null-terminated or ....
> snip...
> >
> > - Bob
>
> In my view, the abstraction that is important here is that of the array
> rather than that of the subprogram seeing a slice as always beginning with
> Index'first. The characteristics of the abstraction of an array should be as
> consistent in Ada as possible.
As consistent as possible, but no more so. ;-)
Enumerations and integers have much in common (that's why they're both
part of the class of discrete types). But there are some important
differences, and I don't think you can get away with pretending they're
the same thing.
We should avoid _gratuitous_ inconsistencies.
>... While having the first value of a String and
> whatever types of arrays you think are appropriate always be the first value
> of the index type would save some memory and computation time,...
It would also reduce the number of bugs, I think. (In particular, it
would prevent the confusion shown by the original example at the start
of this thread.)
We know how to write code that correctly handles all Strings, including
those with bounds 100..101, but Ada should be designed to prevent
accidental errors, even in the presence of fallible programmers.
>... Ada is one of
> the few languages where the array is a powerful and safe abstraction. It is
> therefore much more useful than in other languages, making consistency of
> behavior all the more important and, I think, worth the price in
> computation. To make arrays robust and safe in C type languages,...
I'm comparing Ada to an Ada-like language that is slightly different
(and, I claim, slightly better). I'm not comparing it to C. Ada arrays
are obviously far superior to C arrays in many ways!
>... for
> instance, involves adding a lot more baggage than an extra integer value and
> a little bit of computation done transparently by the compiler.
It's not always transparent. For example, Dmitry pointed out the
example of a procedure that takes two arrays, and wants to perform some
operation on pairs of elements from each. If you can assume that the
two arrays have equal lower bounds, the source code becomes much simpler
(and therefore less error prone).
I'll grant you that you must then remember which array types allow that
assumption. But that's already an issue, since you can fix _both_
bounds in Ada (and you have to remember you did that). For example:
type Char_Mapping is array(Character) of Character;
procedure P(X, Y: Character_Mapping) is
begin
for I in Character loop -- or, equivalently, Char_Mapping'Range
Do_Something(X(I), Y(I));
I claim that's perfectly reasonable code to write -- yet it would be
wrong if Char_Mapping had not fixed the bounds (that is, if it said
"range <>").
- Bob
.
- Follow-Ups:
- Re: Surprise in array concatenation
- From: Jeffrey Carter
- Re: Surprise in array concatenation
- References:
- Re: Surprise in array concatenation
- From: Gene
- Re: Surprise in array concatenation
- From: tmoran
- Re: Surprise in array concatenation
- From: Robert A Duff
- Re: Surprise in array concatenation
- From: Bob Spooner
- Re: Surprise in array concatenation
- Prev by Date: Re: Surprise in array concatenation
- Next by Date: Re: Surprise in array concatenation
- Previous by thread: Re: Surprise in array concatenation
- Next by thread: Re: Surprise in array concatenation
- Index(es):
Relevant Pages
|