Version 1.1 of ai12s/ai12-0300-1.txt

Unformatted version of ai12s/ai12-0300-1.txt version 1.1
Other versions for file ai12s/ai12-0300-1.txt

!standard G.2.3(23)          19-01-07 AI12-0300-1/01
!class binding interpretation 19-01-07
!status work item 19-01-07
!status received 18-12-11
!priority Low
!difficulty Easy
!qualifier Clarification
!subject Annex G text for Fixed * integer
!summary
Fixed values can only be directly multipled by type Integer.
!question
G.2.3(23) says in part:
A multiplication P * Q of an operand of a fixed point type F by an operand of an integer type I, or vice-versa, and a division P / Q of an operand of a fixed point type F by an operand of an integer type I, are also allowed. In these cases, the result has a type of F; explicit conversion of the result is never required.
This implies that (any-fixed * any-integer) is supported, when in fact (any-fixed * Integer) is what that language allows. We had a customer who presumed there was something wrong with the compiler because it didn't allow a (fixed * My_Integer_Type) computation without an explicit conversion.
Should this be fixed? (Yes.)
!recommendation
(See Summary.)
!wording
Modify G.2.3(23):
A multiplication P * Q of an operand of a fixed point type F by an operand of [an integer type I] {type Integer}, or vice-versa, and a division P / Q of an operand of a fixed point type F by an operand of [an integer type I] {type Integer}, are also allowed. In these cases, the result has a type of F; explicit conversion of the result is never required. The accuracy required in these cases is the same as that required for a multiplication F(P * Q) or a division F(P / Q) obtained by interpreting the operand of the integer type to have a fixed point type with a small of 1.0.
!discussion
The multiplying operators for fixed point types are defined in 4.5.5, which include:
function "*"(Left : T; Right : Integer) return T function "*"(Left : Integer; Right : T) return T function "/"(Left : T; Right : Integer) return T
No other operators are defined with fixed and integer operands. (The root-real and root-integer operators are only usable with values of universal types.)
!corrigendum G.2.3(23)
Replace the paragraph:
A multiplication P * Q of an operand of a fixed point type F by an operand of an integer type I, or vice-versa, and a division P / Q of an operand of a fixed point type F by an operand of an integer type I, are also allowed. In these cases, the result has a type of F; explicit conversion of the result is never required. The accuracy required in these cases is the same as that required for a multiplication F(P * Q) or a division F(P / Q) obtained by interpreting the operand of the integer type to have a fixed point type with a small of 1.0.
by:
A multiplication P * Q of an operand of a fixed point type F by an operand of type Integer, or vice-versa, and a division P / Q of an operand of a fixed point type F by an operand of type Integer, are also allowed. In these cases, the result has a type of F; explicit conversion of the result is never required. The accuracy required in these cases is the same as that required for a multiplication F(P * Q) or a division F(P / Q) obtained by interpreting the operand of the integer type to have a fixed point type with a small of 1.0.
!ASIS
No ASIS effect.
!ACATS test
This should be covered by the usual tests for 4.5.5, and any accuracy tests for G.2.3.
!appendix

From: Tucker Taft
Sent: Tuesday, December 11, 2018  8:35 AM

We just bumped into the following misleading text in G.2.3(23):

23 A multiplication P * Q of an operand of a fixed point type F by an 
   operand of an integer type I, or vice-versa, and a division P / Q 
   of an operand of a fixed point type F by an operand of an integer type I,
   are also allowed. In these cases, the result has a type of F; explicit 
   conversion of the result is never required. 

This implies that (any-fixed * any-integer) is supported, when in fact 
(any-fixed * Integer) is what that language allows.  We had a customer who 
presumed there was something wrong with the compiler because it didn't allow
a (fixed * My_Integer_Type) computation without an explicit conversion.

The obvious fix to paragraph 6.2.3(23) is as follows:

23 A multiplication P * Q of an operand of a fixed point type F by an 
   operand of [an integer type I] {type Integer}, or vice-versa, and a
   division P / Q of an operand of a fixed point type F by an operand of
   [an integer type I] {type Integer}, are also allowed. In these cases,
   the result has a type of F; explicit conversion of the result is never
   required. 

****************************************************************

From: Jean-Pierre Rosen
Sent: Tuesday, December 11, 2018  9:33 AM

> This implies that (any-fixed * any-integer) is supported, when in fact 
> (any-fixed * Integer) is what that language allows.

True, and I regret it ever since Ada83. It's presumably too late for Ada 2020,
but it is one of the few cases where you cannot escape Integer.
Maybe due to some resolution issue?

****************************************************************

From: Edmond Schonberg
Sent: Tuesday, December 11, 2018  9:40 AM

The motivation is probably lost to history, but i would imagine that this 
operation is intended as a scaling of a fixed value by a factor that is a 
pure number (I would say dimensionless) and Integer is the only one that makes
sense, YMMV.

****************************************************************

From: Tucker Taft
Sent: Tuesday, December 11, 2018  10:13 AM

I agree, that is the intent I would associate with this choice.  It is similar 
to the rule for exponentiation, where the exponent has to be Integer.

****************************************************************

From: Erhard Ploedereder
Sent: Wednesday, December 12, 2018  7:35 PM

Hmmm. I look at A.1. and see
29
   function "*" (Left : root_integer; Right : root_real)
     return root_real;
30
   function "*" (Left : root_real;    Right : root_integer)
     return root_real;

and words elewhere (in 3.*) that make root_real an ancestor of all float and 
fixed-point types, while root_integer is ancestor to all integer types.

What makes you say that the language allows only
  function "*"(left: any-fixed; Right: Integer) ?

****************************************************************

From: Tucker Taft
Sent: Wednesday, December 12, 2018  7:44 PM

The predefined operators are not inherited.  They appear where they are 
defined to appear in Chapter 4 (see 4.5(9) for the general rule).  Yes, this
is a language kludge, but it is an *old* kludge... ;-)

The only predefined multiplying operators between fixed-point and integer 
types require Standard.Integer, as defined in 4.5.5.  AARM 4.5.5(15.a) 
addresses the issue about the multiplying operators between root-real and 
root-integer, and how they are *not* more generally usable.

****************************************************************

From: Tucker Taft
Sent: Tuesday, December 11, 2018  8:35 AM

****************************************************************

Questions? Ask the ACAA Technical Agent