Allow 1..10 as a discrete range in loops 850916 AI00140/01 1
 !standard 03.06.01 (02) 850916 AI00140/01
!class study 840206 (provisional classification)
!status received 840206
!topic Allow 1..10 as a discrete range in loops
!abstract 840316
The rule disallowing ranges such as 1..10 in iteration rules, constrained
array type declarations, and entry family declarations should be changed to
allow any expression having the type universal_integer as both bounds of the
range.
!recommendation 840316
!wording 840316
!discussion 840316
 !appendix 850916
******************************************************************************
!section 03.06.01 (02) J. Goodenough 831118 8300211
!version 1983
!topic legality of 1..10
The rule in this paragraph makes
for I in 1..10 loop
illegal when an implementation has more than one integer type declared in
STANDARD and legal when an implementation has decided to support only one
predefined integer type.
To see this, consider the case where INTEGER is the only type declared in
STANDARD. 1 (and 10) are either of type universal integer or can be implicitly
converted to any integer type in scope, namely INTEGER and COUNT (which is
declared in TEXT_IO) (the implicit conversion to COUNT is a red herring, so
don't worry too much about it). We now ask what unary "" operators are
visible that take operands of type universal integer, INTEGER, and COUNT, and
find that only the operators for universal integer and INTEGER are visible.
(since we have not said "with TEXT_IO; use TEXT_IO"). Hence, the bounds of the
range can be either of type universal integer or INTEGER. We now apply the
first sentence of 3.6.1(2):
... an implicit conversion to the predefined type INTEGER is assumed if
each bound is either a numeric literal, a named number, or an attribute,
and the type of both bounds (prior to the implicit conversion) is the type
universal integer.
Although 1 can have the type universal integer, it is not a numeric literal.
Since the expression 1 fails the first criterion, this part of the rule does
Allow 1..10 as a discrete range in loops 850916 AI00140/01 2
not apply. We now go on to the rest of the rule:
Otherwise, both bounds must be of the same discrete type, other than
universal integer; this type must be determinable independently of the
context, but using the fact that the type must be discrete and that both
bounds must have the same type.
The first phrase says the bounds cannot be of type universal integer. This
leaves only the possibility that the bounds are of type INTEGER. Since both
bounds have the same discrete type, and the type has been determined
independent of the context, 1..10 is legal, and the bounds are of type
INTEGER.
Now if LONG_INTEGER were also declared in STANDARD, then the second part of the
rule allows the bounds to be either of type INTEGER or LONG_INTEGER. Since the
type of the bounds cannot be resolved, 1..10 is illegal.
In short, the legality of 1..10 depends on whether an implementation has
chosen to implement more than one integer type! This was surely not the
intent and is, to my way of thinking, even more repugnant than having 1..10
illegal when there are two integer types declared in STANDARD.
I believe the rule was intended to read:
if the type of both bounds is universal integer prior to any implicit
conversion, then each bound must be either a numeric literal, a named
number or an attribute, and an implicit conversion to the predefined type
INTEGER is assumed. Otherwise, ... [as before]
Although this was probably the intent (see comment #3705), there really would
have been no harm in allowing 1..10 to be legal by providing a preference for
an implicit conversion to INTEGER in this case. The rule probably should make
F..G illegal if both F and G are userdefined functions overloaded to produce
more than one discrete type; the preference rule should apply only to
expressions that can be of type universal integer. Since such expressions can
also be of type INTEGER (either by direct implicit conversion or by implicitly
converting some operand lower in the syntax tree), it is sufficient to say that
the type of the expression is assumed to be INTEGER when the preference rule is
to be applied. A possible rule would be:
For a discrete range used in a constrained array definition and defined
by a range, if each bound is allowed to have the type universal integer
and the type predefined INTEGER (when other rules of the language are
considered), then both bounds are assumed to be of type predefined
INTEGER. Otherwise, ...
In short, making 1..10 legal when only one integer type is defined by an
implementation is a mistake that should definitely be corrected. It can be
corrected either by making such a range always illegal (in the contexts
specified currently by the RM), or preferably, by making the range always
legal.
Allow 1..10 as a discrete range in loops 850916 AI00140/01 3
******************************************************************************
!section 03.06.01 (02) 8.6(2) P. N. Hilfinger 831119 8300216
!version 1983
!topic legality of 1..10
!reference 8300211
I second John's suggestion that we change 3.6.1(2) to fix the unintentional
implementation dependency and to make 1..10 legal. I believe that the
illegality of the latter is also unintentional, since the rationale given
for the change that made this illegal concerned only ranges used in arrays.
(It said something to the effect that arrays dimensioned, e.g., 1..10
aren't all that useful anyway. For the record, I believe that contention is
probably false too.)
Others have pointed out that technically, the problem is even worse than
this. According to 8.6(2), some incompletely determined subset of the
library units in the library are in scope for any compilation unit (they
aren't visible, however.) This means that in fact, even if there is only
one integer type in STANDARD, the range 1..10 MAY be ambiguous (under the
current wording) if there is a library unit containing a numeric type
declaration (possibly one that is not WITHed either directly or indirectly
by any compilation unit involved in the entire program!)
******************************************************************************
!section 03.06.01 (02) J. L. Gailly 831121 8300218
!version 1983
!topic legality of 1 .. 10
!reference 8300211
The intent was that 1..10 is always illegal in this context. The only
rules you can apply to resolve the overloading are given explicitly: the
type must be dicrete and both bounds must have the same type. In
particular, you cannot use the fact that the type must not be
universal_integer, so you have at least two candidates (universal_integer
and INTEGER) and consequently 1..10 is ambiguous.
I agree that this result is not desirable (it is still better than having
to count the number of integer types in scope). However, all proposed
solutions seen so far are ambiguous or contradictory with 4.6(15). The
proposal made by Taffs in #3705 and #5435 requires oveloading resolution in
two stages: first, try to resolve without any special rule; then if this
failed, apply an implicit qualification (NOT a conversion) by the type
INTEGER (this is my interpreation of his sentence "the wording must provide
a particular context, rather than apply a particular implicit conversion").
Taffs is right in saying that his proposed rule does not add complexity to
the implementation of overloading resolution (one bottomup then one
topdown pass is still sufficient), but the two passes are logically
different. Taffs' solution also resolves examples that were intended to be
ambiguous (see #3705), but these examples are pathological.
Allow 1..10 as a discrete range in loops 850916 AI00140/01 4
John G. also suggests a preference rule for INTEGER when only
universal_integer and INTEGER are candidate types: this rule does not seem
to solve the problem of the presence or absence of LONG_INTEGER. (May be
he meant "if each bound is allowed to have a predefined integer type ...",
but that would also resolve arbitrarily ambiguities created by the user
with explicit redefinitions of operators.) It is also not clear whether
"assumed to be" means implicit qualification (as in Taffs' solution),
implicit conversion (in contradiction with 4.6(15)), or is a new concept in
Ada.
I believe that a solution using implicit qualification could work (although
it leads sometimes to unexpected results), but I don't have a good wording
to suggest. It is also possible to modify 4.6(15), saying that 3.6.1(2) is
the only case where the rule defining convertible operands does not apply.
3.6.1(2) would then say "if both bounds are of type universal_integer, then
each bound is implicitly converted to the predefined type INTEGER".
The two solutions (implicit qualification or implicit conversion) yield
different results only for pathological examples; the solution using
conversion is closer to what most users would intuitively expect.
******************************************************************************
!section 03.06.01 (02) J. Goodenough 831121 8300219
!version 1983
!topic legality of 1..10
!reference 8300216
The problem is really independent of 8.6(2), since even if more than one
integer type is technically in scope because it is in some library unit that is
not with'd, the unary minus operator for that type will not be visible, and so
the additional integer type creates no ambiguity. In essence, the final
determiners of ambiguity are the visible operators, not the types that are in
scope.
******************************************************************************
!section 03.06.01 (02) J. Goodenough 831122 8300220
!version 1983
!topic legality of 1..10
!reference 8300218
My proposed wording did not say that "when only universal_integer and INTEGER
are candidate types"; it said, in effect, when universal_integer and INTEGER
(at least) are candidate types. Hence, if LONG_INTEGER is also a candidate,
the resolution to INTEGER is chosen.
My proposed wording is equivalent to an implicit qualification of the bounds
when there is otherwise no way to choose. My phasing "assumed to be" was
suggested by the current phrasing; how about saying "then both bounds are
required to be of predefined type INTEGER." I don't really care whether the
bounds are disambiguated by qualification or by implicit conversion from
Allow 1..10 as a discrete range in loops 850916 AI00140/01 5
universal integer, since as #3705 shows, only highly pathological cases are
likely to be affected.
My proposed rule does not contradict 4.6(15) since it specifies a condition
under which the result type universal_integer is not allowed, but for optimal
clarity, 4.6(15) should also metntion the rule in 3.6.2.
******************************************************************************
!section 03.06.01 (02) Peter Belmont / Intermetrics 831129 8300228
!version 1983
!topic legality and meaning of 1..10
This question is one which begs, I think, for a statement of
REQUIREMENTS on the design and/or interpretation. For myself,
I would state the requirement as one of simplicity, completeness
and nonsurprisingness, and parallelism with the other Ada
construct which presents a similar problem, (1<10).
I would like "1" to be treated as a literal in contexts which
do not force conversions to nonuniversal types.
Now, how do we treat
( 1 < 10 ) ?
As I understand it, we see that it is possible to understand this
without applying implicit conversions. That is, we treat the
"1" as a universal integer, as a literal.
I propose that we seek to restate the LRM to achieve the same
effect. Treat
exp1 .. exp2
as a construct that allows an interpretation
in universal integers. And then, in a postprocessing step,
convert to INTEGER.
If you like this, one could rewrite the paragraph:
A discrete range defined by a range and used
in a constrained array definition (see 3.6),
in an iteration rule (see 5.5), or in the declaration
of a family of entries (see 9.5) is subject to the following
rule.
The two bounds must be of the same discrete type, which
may be universal integer. If
they are both of type universal integer, then an implicit
conversion of both bounds to the predefined type INTEGER
is applied after the bounds are elaborated.
Allow 1..10 as a discrete range in loops 850916 AI00140/01 6
Discussion. First, this makes a good parallel with ( 1 < 10 ).
Second, it handles 1..10 as we intuitively expect it to be
handled. Third, in a case like
1 .. INTVAR
an implicit conversion of the 1 to INTEGER (allowing an INTEGER
interpretation of the 1) is always available (see 4.6(15)) in
any case. Fourth, we leave no holes (that I can see). Fifth,
nonstatic universal values (from T'LENGTH(2)) are OK; conversion
to INTEGER may raise an exception at runtime.
Question: Why does the LRM place such an odd restriction on
the expressions which will be converted to INTEGER? What important
interest is served by providing a friendly home for 1..10 but
a cold winter wind for 100..1? Why should I get in
trouble for writing 0..T'LENGTH1 when
I am allowed 1..T'LENGTH without demur?
******************************************************************************
!section 03.06.01 (02) Jean D. Ichbiah 840301 8300309
!version 1983
!topic legality of 1 .. 10
!reference 83211 and 83218
I agree with comment 83218 (and disagree with 83211): The following
declaration is illegal
A : array(1 .. 10) of CHIPMUNK;
The reason  as pointed out by JL Gailly  is given by the sentences:
(a) Otherwise, both bounds must be of the same discrete type, other
than universal_integer;
(b) this type must be determinable independently of the context, but
using the fact that the type must be discrete and that both
bounds must have the same type.
So, for overload resolution of the range 1 .. 10 we proceed as follows:
. First we cannot apply the first sentence of 3.6.1(2) since "1"
is not a literal (so far 83211 is correct).
. Hence we try to apply the second sentence (reproduced above). But
this yields at least 2 possible interpretations of the
subsentence (b):
 The operator "" in "1" is the unary operator that applies to
universal_integers. Both bounds are of type universal integer.
Allow 1..10 as a discrete range in loops 850916 AI00140/01 7
 Apply implicit conversions to INTEGER to the two literals "1"
and "10" then the INTEGER "" operator.
. Consequently there are two possible types and the type is not
uniquely determinable for the context. (Note that (b) excludes
the use of (a) for this determination.)
Hence the statement given in 83211 (that legality is
implementation_dependent) is incorrect.
Concerning functionality, I do not see any reason for a change:
(a) Positive ranges are quite common and are well covered by the
rule.
(b) Negative ranges are very rare: they already assume a
sophisticated programmer, and in such a case the available tools
are sufficient:
A : array(INTEGER range 10 .. 10) of ...
for N in A'RANGE loop ...
for N in INTEGER range 10 .. 10 loop ...
(c) Why make the rules more complex?
 ******************************************************************************

 !section 03.06.01 (02) RD Pogge/Naval Weapons Ctr 850814 8300641
 !version 1983
 !topic Invalid bounds

 The first sentence of 3.6.1, paragraph 2, contains a long
 list of bounds converted from Universal_Integer to Integer.
 However, it has been interpreted by at least one validated
 compiler that 1..5 is an invalid construct because 1 is a
 simple expression of type Universal_Integer and 5 is a
 numeric literal which is converted to type Integer, so the
 bounds are of different types. We recommend a rewording of
 3.6.1(2) to be:
 ...a numeric literal, a simple expression, a named number...

 The following:
 "for i in 10..10 loop"
 "is array (1..1) of.."
 should be legal, and the validation test suite should check
 to make sure that they are.