comp.lang.ada
 help / color / mirror / Atom feed
* Array conversion and bounds
@ 2018-04-15  9:36 Dmitry A. Kazakov
  2018-04-15 10:37 ` Niklas Holsti
  2018-04-15 17:55 ` Robert A Duff
  0 siblings, 2 replies; 9+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-15  9:36 UTC (permalink / raw)


Do array bounds slide during conversion? Consider this:

    type A is array (Integer range <>) of Whatever;
    type B is array (Unsigned_32 range <>) of Whatever;

    X : A (-10..-1);
    Y : B (1..10);
begin
    Y := B (X); -- Is this OK?

If bounds slide it must be OK, if bounds do not slide, it must raise 
Constraint_Error.

Any language lawyers?

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15  9:36 Array conversion and bounds Dmitry A. Kazakov
@ 2018-04-15 10:37 ` Niklas Holsti
  2018-04-15 12:34   ` Dmitry A. Kazakov
  2018-04-15 17:55 ` Robert A Duff
  1 sibling, 1 reply; 9+ messages in thread
From: Niklas Holsti @ 2018-04-15 10:37 UTC (permalink / raw)


On 18-04-15 12:36 , Dmitry A. Kazakov wrote:
> Do array bounds slide during conversion? Consider this:
>
>    type A is array (Integer range <>) of Whatever;
>    type B is array (Unsigned_32 range <>) of Whatever;
>
>    X : A (-10..-1);
>    Y : B (1..10);
> begin
>    Y := B (X); -- Is this OK?
>
> If bounds slide it must be OK, if bounds do not slide, it must raise
> Constraint_Error.
>
> Any language lawyers?

I believe the bounds should _not_ slide, because the "target subtype" of 
the conversion is type B, which is an _unconstrained_ array subtype.

Conversions to an unconstrained array subtype are governed by RM 4.6(38):

"If the target subtype is an unconstrained array subtype, then the 
bounds of the result are obtained by converting each bound of the value 
of the operand to the corresponding index type of the target type. For 
each nonnull index range, a check is made that the bounds of the range 
belong to the corresponding index subtype."

Since -10 and -1 do not below to Unsigned_32, the conversion should 
raise Constraint_Error.

This, deceptively similar, code should use sliding: the changes are to 
introduce

    subtype B_10 is B (1..10);

and change the conversion to B_10 (X). Now the "target subtype" is B_10, 
which is constrained, and then the conversion follows RM 4.6(37), 
especially the last sentence:

"If the target subtype is a constrained array subtype, then a check is 
made that the length of each dimension of the value of the operand 
equals the length of the corresponding dimension of the target subtype. 
The bounds of the result are those of the target subtype."

RM 4.6(39) then says how the components of the result are defined:

"In either array case, the value of each component of the result is that 
of the matching component of the operand value (see 4.5.2)."

The specification of "matching component" means sliding, if the index 
ranges of the source and target are different.

Caution: I have only "proved" the above against the Ada RM, but not 
tested it :-)

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15 10:37 ` Niklas Holsti
@ 2018-04-15 12:34   ` Dmitry A. Kazakov
  2018-04-15 13:11     ` Niklas Holsti
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-15 12:34 UTC (permalink / raw)


On 2018-04-15 12:37, Niklas Holsti wrote:
> On 18-04-15 12:36 , Dmitry A. Kazakov wrote:
>> Do array bounds slide during conversion? Consider this:
>>
>>    type A is array (Integer range <>) of Whatever;
>>    type B is array (Unsigned_32 range <>) of Whatever;
>>
>>    X : A (-10..-1);
>>    Y : B (1..10);
>> begin
>>    Y := B (X); -- Is this OK?
>>
>> If bounds slide it must be OK, if bounds do not slide, it must raise
>> Constraint_Error.
>>
>> Any language lawyers?
> 
> I believe the bounds should _not_ slide, because the "target subtype" of 
> the conversion is type B, which is an _unconstrained_ array subtype.

Better to say, they should, but they do not. Clearly conversions like 
this should not require resorting to Unchecked_Conversion.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15 12:34   ` Dmitry A. Kazakov
@ 2018-04-15 13:11     ` Niklas Holsti
  2018-04-15 13:24       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 9+ messages in thread
From: Niklas Holsti @ 2018-04-15 13:11 UTC (permalink / raw)


On 18-04-15 15:34 , Dmitry A. Kazakov wrote:
> On 2018-04-15 12:37, Niklas Holsti wrote:
>> On 18-04-15 12:36 , Dmitry A. Kazakov wrote:
>>> Do array bounds slide during conversion? Consider this:
>>>
>>>    type A is array (Integer range <>) of Whatever;
>>>    type B is array (Unsigned_32 range <>) of Whatever;
>>>
>>>    X : A (-10..-1);
>>>    Y : B (1..10);
>>> begin
>>>    Y := B (X); -- Is this OK?
>>>
>>> If bounds slide it must be OK, if bounds do not slide, it must raise
>>> Constraint_Error.
>>>
>>> Any language lawyers?
>>
>> I believe the bounds should _not_ slide, because the "target subtype"
>> of the conversion is type B, which is an _unconstrained_ array subtype.
>
> Better to say, they should, but they do not.

Ok, if I read the RM correctly (and you seem to agree with me) they "do 
not" slide when the target subtype is unconstrained.

> Clearly conversions like this should not require resorting to
> Unchecked_Conversion.

Is there some reason why you cannot use the constrained-target-subtype 
method to force sliding?

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15 13:11     ` Niklas Holsti
@ 2018-04-15 13:24       ` Dmitry A. Kazakov
  2018-04-15 18:21         ` Niklas Holsti
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-15 13:24 UTC (permalink / raw)


On 2018-04-15 15:11, Niklas Holsti wrote:
> On 18-04-15 15:34 , Dmitry A. Kazakov wrote:
>> On 2018-04-15 12:37, Niklas Holsti wrote:
>>> On 18-04-15 12:36 , Dmitry A. Kazakov wrote:
>>>> Do array bounds slide during conversion? Consider this:
>>>>
>>>>    type A is array (Integer range <>) of Whatever;
>>>>    type B is array (Unsigned_32 range <>) of Whatever;
>>>>
>>>>    X : A (-10..-1);
>>>>    Y : B (1..10);
>>>> begin
>>>>    Y := B (X); -- Is this OK?
>>>>
>>>> If bounds slide it must be OK, if bounds do not slide, it must raise
>>>> Constraint_Error.
>>>>
>>>> Any language lawyers?
>>>
>>> I believe the bounds should _not_ slide, because the "target subtype"
>>> of the conversion is type B, which is an _unconstrained_ array subtype.
>>
>> Better to say, they should, but they do not.
> 
> Ok, if I read the RM correctly (and you seem to agree with me) they "do 
> not" slide when the target subtype is unconstrained.

It is an unsafe choice, obviously.

>> Clearly conversions like this should not require resorting to
>> Unchecked_Conversion.
> 
> Is there some reason why you cannot use the constrained-target-subtype 
> method to force sliding?

Considering this example:

    type A is array (Integer range <>) of Whatever;
    type B is array (Unsigned_32 range <>) of Whatever;

    X : A (-1000..-1);
    Y : B (1..200);
begin
    Y (10..19) := B (X (-19..-10));

Do you propose this?

    declare
       subtype BB is B (10..19);
    begin
       Y (10..19) := BB (X (-19..-10));
    end;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15  9:36 Array conversion and bounds Dmitry A. Kazakov
  2018-04-15 10:37 ` Niklas Holsti
@ 2018-04-15 17:55 ` Robert A Duff
  2018-04-15 20:15   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 9+ messages in thread
From: Robert A Duff @ 2018-04-15 17:55 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

>    type B is array (Unsigned_32 range <>) of Whatever;

An unconstrained array with modular index type is
asking for trouble.

- Bob


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15 13:24       ` Dmitry A. Kazakov
@ 2018-04-15 18:21         ` Niklas Holsti
  2018-04-15 20:29           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 9+ messages in thread
From: Niklas Holsti @ 2018-04-15 18:21 UTC (permalink / raw)


On 18-04-15 16:24 , Dmitry A. Kazakov wrote:
> On 2018-04-15 15:11, Niklas Holsti wrote:
>> On 18-04-15 15:34 , Dmitry A. Kazakov wrote:
>>> On 2018-04-15 12:37, Niklas Holsti wrote:
>>>> On 18-04-15 12:36 , Dmitry A. Kazakov wrote:
>>>>> Do array bounds slide during conversion? Consider this:
>>>>>
>>>>>    type A is array (Integer range <>) of Whatever;
>>>>>    type B is array (Unsigned_32 range <>) of Whatever;
>>>>>
>>>>>    X : A (-10..-1);
>>>>>    Y : B (1..10);
>>>>> begin
>>>>>    Y := B (X); -- Is this OK?
>>>>>
>>>>> If bounds slide it must be OK, if bounds do not slide, it must raise
>>>>> Constraint_Error.
>>>>>
>>>>> Any language lawyers?
>>>>
>>>> I believe the bounds should _not_ slide, because the "target subtype"
>>>> of the conversion is type B, which is an _unconstrained_ array subtype.
>>>
>>> Better to say, they should, but they do not.
>>
>> Ok, if I read the RM correctly (and you seem to agree with me) they
>> "do not" slide when the target subtype is unconstrained.
>
> It is an unsafe choice, obviously.

Not obvious, I think.

I think you'll agree with me that Ada array types are a blend (sometimes 
uneasy) of two kinds of conceptual data structures: (1) maps from the 
index type(s) to the component type, and (2) ordered sequences or 
matrices of values of the component type.

An example of the first case is an array indexed by calendar year number 
and giving the average global temperature for that year. An example of 
the second case is a string, where the index (usually) shows only the 
relative order of characters in the string.

In the first case, the association of a specific index value with the 
corresponding component value is meaningful, and should not be lightly 
destroyed by sliding, because sliding could give unexpected associations 
-- for example, the global average temperature for 2005 could wrongly 
become associated with the year 1. In the second case, sliding is 
harmless, as the string (1 => 'H', 2 => 'i') is (in most cases) 
equivalent to the string (100 => 'H', 101 => 'i').

>> Is there some reason why you cannot use the constrained-target-subtype
>> method to force sliding?
>
> Considering this example:
>
>    type A is array (Integer range <>) of Whatever;
>    type B is array (Unsigned_32 range <>) of Whatever;
>
>    X : A (-1000..-1);
>    Y : B (1..200);
> begin
>    Y (10..19) := B (X (-19..-10));
>
> Do you propose this?
>
>    declare
>       subtype BB is B (10..19);
>    begin
>       Y (10..19) := BB (X (-19..-10));
>    end;

Yes. And BB might have any index range, as long as BB'Length = 10.

I admit that I did not know by heart these rules (sliding for 
constrained target subtype, no sliding for unconstrained) but now I feel 
that they are rather natural. A conversion to a constrained target 
subtype says "give me these index bounds, and no others" so sliding is 
apt. A conversion to an unconstrained target subtype says "I do not 
require specific index bounds, so the bounds of the source array are as 
good as any others".

The case of an unconstrained target subtype, but where the source bounds 
are not (or might not be) in the target index subtype's range, is 
perhaps a trap in the language, and worth a compiler warning.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15 17:55 ` Robert A Duff
@ 2018-04-15 20:15   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 9+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-15 20:15 UTC (permalink / raw)


On 2018-04-15 19:55, Robert A Duff wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>>     type B is array (Unsigned_32 range <>) of Whatever;
> 
> An unconstrained array with modular index type is
> asking for trouble.

No matter, take these two instead:

    type A is array (Integer_16 range <>) of Whatever;
    type B is array (Integer_8 range <>) of Whatever;

    Y (1..10) := B (X (1001..1010));

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Array conversion and bounds
  2018-04-15 18:21         ` Niklas Holsti
@ 2018-04-15 20:29           ` Dmitry A. Kazakov
  0 siblings, 0 replies; 9+ messages in thread
From: Dmitry A. Kazakov @ 2018-04-15 20:29 UTC (permalink / raw)


On 2018-04-15 20:21, Niklas Holsti wrote:
> On 18-04-15 16:24 , Dmitry A. Kazakov wrote:
>> On 2018-04-15 15:11, Niklas Holsti wrote:
>>> On 18-04-15 15:34 , Dmitry A. Kazakov wrote:
>>>> On 2018-04-15 12:37, Niklas Holsti wrote:
>>>>> On 18-04-15 12:36 , Dmitry A. Kazakov wrote:
>>>>>> Do array bounds slide during conversion? Consider this:
>>>>>>
>>>>>>    type A is array (Integer range <>) of Whatever;
>>>>>>    type B is array (Unsigned_32 range <>) of Whatever;
>>>>>>
>>>>>>    X : A (-10..-1);
>>>>>>    Y : B (1..10);
>>>>>> begin
>>>>>>    Y := B (X); -- Is this OK?
>>>>>>
>>>>>> If bounds slide it must be OK, if bounds do not slide, it must raise
>>>>>> Constraint_Error.
>>>>>>
>>>>>> Any language lawyers?
>>>>>
>>>>> I believe the bounds should _not_ slide, because the "target subtype"
>>>>> of the conversion is type B, which is an _unconstrained_ array 
>>>>> subtype.
>>>>
>>>> Better to say, they should, but they do not.
>>>
>>> Ok, if I read the RM correctly (and you seem to agree with me) they
>>> "do not" slide when the target subtype is unconstrained.
>>
>> It is an unsafe choice, obviously.
> 
> Not obvious, I think.
> 
> I think you'll agree with me that Ada array types are a blend (sometimes 
> uneasy) of two kinds of conceptual data structures: (1) maps from the 
> index type(s) to the component type, and (2) ordered sequences or 
> matrices of values of the component type.
> 
> An example of the first case is an array indexed by calendar year number 
> and giving the average global temperature for that year. An example of 
> the second case is a string, where the index (usually) shows only the 
> relative order of characters in the string.
> 
> In the first case, the association of a specific index value with the 
> corresponding component value is meaningful, and should not be lightly 
> destroyed by sliding, because sliding could give unexpected associations 
> -- for example, the global average temperature for 2005 could wrongly 
> become associated with the year 1. In the second case, sliding is 
> harmless, as the string (1 => 'H', 2 => 'i') is (in most cases) 
> equivalent to the string (100 => 'H', 101 => 'i').

This is all true, but it does not prove the case. Because

1. Indices do slide anyway:

    Y (1..10) := X (B (2..11)); -- This is OK

they raise Constraint_Error only if the starting point of the sliding 
index is out of the range of the target index type.

2. There is no way one the language could judge the way indices to be 
converted. Either an array conversion must be A) always illegal, or B) 
use user-provided index mapping, C) or slide taking only the length in 
account.

>>> Is there some reason why you cannot use the constrained-target-subtype
>>> method to force sliding?
>>
>> Considering this example:
>>
>>    type A is array (Integer range <>) of Whatever;
>>    type B is array (Unsigned_32 range <>) of Whatever;
>>
>>    X : A (-1000..-1);
>>    Y : B (1..200);
>> begin
>>    Y (10..19) := B (X (-19..-10));
>>
>> Do you propose this?
>>
>>    declare
>>       subtype BB is B (10..19);
>>    begin
>>       Y (10..19) := BB (X (-19..-10));
>>    end;
> 
> Yes. And BB might have any index range, as long as BB'Length = 10.
> 
> I admit that I did not know by heart these rules (sliding for 
> constrained target subtype, no sliding for unconstrained) but now I feel 
> that they are rather natural. A conversion to a constrained target 
> subtype says "give me these index bounds, and no others" so sliding is 
> apt. A conversion to an unconstrained target subtype says "I do not 
> require specific index bounds, so the bounds of the source array are as 
> good as any others".

And the compiler chooses the ones that would cause Constraint_Error? 
Constraint_Error is definitely not as good as no Constraint_Error.

> The case of an unconstrained target subtype, but where the source bounds 
> are not (or might not be) in the target index subtype's range, is 
> perhaps a trap in the language, and worth a compiler warning.

It is impossible to warn, because the bounds are unknown until run-time. 
This is a very unsafe choice.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-04-15 20:29 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-15  9:36 Array conversion and bounds Dmitry A. Kazakov
2018-04-15 10:37 ` Niklas Holsti
2018-04-15 12:34   ` Dmitry A. Kazakov
2018-04-15 13:11     ` Niklas Holsti
2018-04-15 13:24       ` Dmitry A. Kazakov
2018-04-15 18:21         ` Niklas Holsti
2018-04-15 20:29           ` Dmitry A. Kazakov
2018-04-15 17:55 ` Robert A Duff
2018-04-15 20:15   ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox