CVS difference for ai12s/ai12-0208-1.txt

Differences between 1.19 and version 1.20
Log of other versions for file ai12s/ai12-0208-1.txt

--- ai12s/ai12-0208-1.txt	2019/02/07 06:31:29	1.19
+++ ai12s/ai12-0208-1.txt	2019/02/22 06:50:38	1.20
@@ -1,4 +1,4 @@
-!standard A.5.5(0)                                   19-02-01  AI12-0208-1/08
+!standard A.5.5(0)                                   19-02-22  AI12-0208-1/09
 !standard A.5.6(0)
 !standard A.5.7(0)
 !standard A.5.8(0)
@@ -29,7 +29,7 @@
 
 Support is provided for integer arithmetic involving values larger than
 than those supported by the target machine, and for arbitrary-precision
-rationals.
+reals.
 
 The package Ada.Numerics.Big_Numbers has the following declaration:
 
@@ -199,111 +199,111 @@
     Default_Initialized_Object : Big_Integer;
   is required to propagate Assertion_Error.
 
-A.5.7 Big Rationals
+A.5.7 Big Reals
 
-The package Numerics.Big_Numbers.Big_Rationals has the
+The package Numerics.Big_Numbers.Big_Reals has the
 following declaration:
 
    with Ada.Numerics.Big_Numbers.Big_Integers;
    with Ada.Streams;
-   package Ada.Numerics.Big_Numbers.Big_Rationals
+   package Ada.Numerics.Big_Numbers.Big_Reals
       with Preelaborate, Nonblocking
    is
       use Big_Integers;
 
-      type Optional_Big_Rational is private with
-        Default_Initial_Condition => not Is_Present (Optional_Big_Rational),
+      type Optional_Big_Real is private with
+        Default_Initial_Condition => not Is_Present (Optional_Big_Real),
         Real_Literal => From_String,
         Put_Image => Put_Image;
 
-      function Is_Present (Arg : Optional_Big_Rational) return Boolean;
+      function Is_Present (Arg : Optional_Big_Real) return Boolean;
 
-      function No_Big_Rational return Optional_Big_Rational
-        with Post => not Is_Present (No_Big_Rational'Result);
+      function No_Big_Real return Optional_Big_Real
+        with Post => not Is_Present (No_Big_Real'Result);
 
-      subtype Big_Rational is Optional_Big_Rational
-        with Dynamic_Predicate => Is_Present (Big_Rational),
+      subtype Big_Real is Optional_Big_Real
+        with Dynamic_Predicate => Is_Present (Big_Real),
              Predicate_Failure => (raise Constraint_Error);
 
-      function "/" (Num, Den : Big_Integer) return Big_Rational
+      function "/" (Num, Den : Big_Integer) return Big_Real
         with Pre => (Den /= 0) or else (raise Constraint_Error);
 
-      function Numerator (Arg : Big_Rational) return Big_Integer;
-      function Denominator (Arg : Big_Rational) return Big_Positive
+      function Numerator (Arg : Big_Real) return Big_Integer;
+      function Denominator (Arg : Big_Real) return Big_Positive
         with Post =>
           (Arg = 0.0) or else
           (Greatest_Common_Divisor
              (Numerator (Arg), Denominator'Result) = 1);
 
-      function To_Big_Rational (Arg : Big_Integer) return Big_Rational is
+      function To_Big_Real (Arg : Big_Integer) return Big_Real is
         (Arg / 1);
 
-      function "+" (Arg : Integer) return Big_Rational
-        renames To_Big_Rational;
+      function "+" (Arg : Integer) return Big_Real
+        renames To_Big_Real;    -- **** Editor's note: This function is nonsense as written.
 
-      function To_Rational (Arg : Integer) return Big_Rational is ((+Arg) / 1);
+      function To_Real (Arg : Integer) return Big_Real is ((+Arg) / 1);
 
-      function "=" (L, R : Big_Rational) return Boolean;
-      function "<" (L, R : Big_Rational) return Boolean;
-      function "<=" (L, R : Big_Rational) return Boolean;
-      function ">" (L, R : Big_Rational) return Boolean;
-      function ">=" (L, R : Big_Rational) return Boolean;
+      function "=" (L, R : Big_Real) return Boolean;
+      function "<" (L, R : Big_Real) return Boolean;
+      function "<=" (L, R : Big_Real) return Boolean;
+      function ">" (L, R : Big_Real) return Boolean;
+      function ">=" (L, R : Big_Real) return Boolean;
 
-      function In_Range (Arg, Low, High : Big_Rational) return Boolean is
+      function In_Range (Arg, Low, High : Big_Real) return Boolean is
         ((Low <= Arg) and (Arg <= High));
 
       generic
          type Num is digits <>;
       package Float_Conversions is
-         function To_Big_Rational (Arg : Num) return Big_Rational;
+         function To_Big_Real (Arg : Num) return Big_Real;
 
-         function From_Big_Rational (Arg : Big_Rational) return Num
+         function From_Big_Real (Arg : Big_Real) return Num
            with Pre => In_Range (Arg,
-                                 Low  => To_Big_Rational (Num'First),
-                                 High => To_Big_Rational (Num'Last))
+                                 Low  => To_Big_Real (Num'First),
+                                 High => To_Big_Real (Num'Last))
                        or else (raise Constraint_Error);
       end Float_Conversions;
 
       generic
          type Num is delta <>;
       package Fixed_Conversions is
-         function To_Big_Rational (Arg : Num) return Big_Rational;
+         function To_Big_Real (Arg : Num) return Big_Real;
 
-         function From_Big_Rational (Arg : Big_Rational) return Num
+         function From_Big_Real (Arg : Big_Real) return Num
            with Pre => In_Range (Arg,
-                                 Low  => To_Big_Rational (Num'First),
-                                 High => To_Big_Rational (Num'Last))
+                                 Low  => To_Big_Real (Num'First),
+                                 High => To_Big_Real (Num'Last))
                        or else (raise Constraint_Error);
       end Fixed_Conversions;
 
-      function To_String (Arg  : Big_Rational;
+      function To_String (Arg  : Big_Real;
                           Fore : Field := 2;
                           Aft  : Field := 3;
                           Exp  : Field := 0) return String
          with Post => To_String'Result'First = 1;
-      function From_String (Arg   : String) return Big_Rational;
+      function From_String (Arg   : String) return Big_Real;
 
-      function To_Quotient_String (Arg : Big_Rational) return String is
+      function To_Quotient_String (Arg : Big_Real) return String is
         (To_String (Numerator (Arg)) & " / " & To_String (Denominator (Arg)));
-      function From_Quotient_String (Arg : String) return Big_Rational;
+      function From_Quotient_String (Arg : String) return Big_Real;
 
       procedure Put_Image
-        (Arg    : Big_Rational;
+        (Arg    : Big_Real;
          Stream : not null access Ada.Streams.Root_Stream_Type'Class);
 
-      function "-" (L : Big_Rational) return Big_Rational;
-      function "abs" (L : Big_Rational) return Big_Rational;
-      function "+" (L, R : Big_Rational) return Big_Rational;
-      function "-" (L, R : Big_Rational) return Big_Rational;
-      function "*" (L, R : Big_Rational) return Big_Rational;
-      function "/" (L, R : Big_Rational) return Big_Rational;
-      function "**" (L : Big_Rational; R : Integer)
-        return Big_Rational;
-      function Min (L, R : Big_Rational) return Big_Rational;
-      function Max (L, R : Big_Rational) return Big_Rational;
+      function "-" (L : Big_Real) return Big_Real;
+      function "abs" (L : Big_Real) return Big_Real;
+      function "+" (L, R : Big_Real) return Big_Real;
+      function "-" (L, R : Big_Real) return Big_Real;
+      function "*" (L, R : Big_Real) return Big_Real;
+      function "/" (L, R : Big_Real) return Big_Real;
+      function "**" (L : Big_Real; R : Integer)
+        return Big_Real;
+      function Min (L, R : Big_Real) return Big_Real;
+      function Max (L, R : Big_Real) return Big_Real;
    private
       ... -- not specified by the language
-   end Ada.Numerics.Big_Numbers.Big_Rationals;
+   end Ada.Numerics.Big_Numbers.Big_Reals;
 
 To_String and From_String behave analogously to the Put and Get procedures
 defined in Text_IO.Float_IO (in particular, with respect to the
@@ -314,9 +314,9 @@
 converts that String to a Wide_Wide_String using To_Wide_Wide_String, and
 the resulting value to the stream using Wide_Wide_String'Write.
 
-For an instance of Float_Conversions or Fixed_Conversions, To_Big_Rational
+For an instance of Float_Conversions or Fixed_Conversions, To_Big_Real
 is exact (i.e., the result represents exactly the same
-mathematical value as the argument) and From_Big_Rational is subject to
+mathematical value as the argument) and From_Big_Real is subject to
 the same precision rules as a type conversion of a value of type T to
 the target type Num, where T is a hypothetical floating point type whose
 model numbers include all of the model numbers of Num as well as the
@@ -325,47 +325,24 @@
 The other functions have their usual mathematical meanings.
 
 Implementation Requirements
-  No storage associated with an Optional_Big_Rational object shall be lost
+  No storage associated with an Optional_Big_Real object shall be lost
   upon assignment or scope exit.
 
   AARM note: The "No storage ... shall be lost" requirement does not preclude
   implementation techniques such as caching or unique number tables.
 
   For purposes of determining whether predicate checks are performed
-  as part of default initialization, the type Optional_Big_Rational
+  as part of default initialization, the type Optional_Big_Real
   shall be considered to have a subcomponent that has a default_expression.
 
   AARM Note: This means that the elaboration of
-    Default_Initialized_Object : Big_Rational;
+    Default_Initialized_Object : Big_Real;
   is required to propagate Assertion_Error.
 
-====
-
-This section, or at least the AARM note, is intended to follow
-the structure of the analogous wording for  AI12-0112-1 (contracts for
-containers).
-
-Add after 11.5(23):
-
-Big_Number_Check
-
-Perform the checks associated with Pre, Static_Predicate, Dynamic_Predicate,
-or Type_Invariant aspect specifications occuring in the visible part of
-package Numerics.Big_Numbers or of any of its descendants.
-
-AARM Reason: One could use the Assertion_Policy to eliminate such checks,
-but that would require recompiling the Ada.Big_Numbers packages (the
-assertion policy that determines whether the checks are made is that
-used to compile the unit). In addition, we do not want to specify the
-behavior of the Ada.Big_Numbers operations if a precondition or predicate
-fails; that is different than the usual behavior of Assertion_Policy.
-By using Suppress for this purpose, we make it clear that suppressing
-a check that would have failed results in erroneous execution.
-
-
 !discussion
 
-** None yet.
+We presume that AI12-0311-1 is approved, which will allow the preconditions
+and predicates of these packages to be suppressed.
 
 !ASIS
 
@@ -6396,5 +6373,336 @@
 
 [See the last part of Randy's message of January 8, 2019 7:56 PM 
 for this text - Editor.]
+
+****************************************************************
+
+From: John Barnes
+Sent: Thursday, February  7, 2019   7:06 AM
+
+I have  been fretting about this topic for some time – with some restless 
+nights.
+
+Please find attached some thoughts. I fear they are in Word rather than plain 
+text for typographical reasons.
+
+[Editor's note: These thoughts are found in the Grab-Bag on Ada-Auth.org:
+  http://www.ada-auth.org/ai-files/grab_bag/literals.pdf  ]
+
+Jeff has helped me with getting  my thoughts in order for which I am most 
+grateful.
+
+I also have a problem with being very busy with a course at Oxford this term.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February  7, 2019   7:45 PM
+
+>I have  been fretting about this topic for some time - with some 
+>restless nights.
+
+I'm the only one that's allowed to have sleepless nights over unimportant Ada 
+issues. ;-)
+
+>Please find attached some thoughts. 
+
+[Some thoughts quoted below...]
+
+> So what to do. Well maybe change AI-249 to provide only one literal 
+> and please call it just Literal and change the !subject of the AI to 
+> "User-defined literals".
+
+The problem with this is that there are three other kinds of user-defined 
+literals defined in other AIs. We adopted the string literal AI as well (left 
+the character and null literals for the future, since uses of those are a 
+stretch).
+
+Merging real and integer literals also has the very significant downside of 
+changing a compile-time error into an exception raised in the case of 
+operations that only want integer literals (like Big_Integer). If 
+   Int : Big_Integer := 3.14;
+is legal but raises an exception at runtime, we've lost something significant.
+
+>I think that if AI-249 defines aspects for Real_Literal and 
+>Integer_Literal
+
+>then it ought to say exactly what they are.
+
+They correspond to a use of the corresponding lexical construct. This is 
+described in the Dynamic Semantics of each aspect (see 4.2.1 in the draft
+RM):
+
+  For the evaluation of an integer (or real) literal with expected type
+  having an Integer_Literal (or Real_Literal) aspect specified ...
+
+There might be a clearer way to state this in the wording, and especially in 
+the AI presentation, but that's the point of editorial review.
+
+One thing that immediately stands out to me is that it isn't clear that this 
+is really two separate rules:
+
+  For the evaluation of an integer literal with expected type having an
+  Integer_Literal aspect specified ...
+
+and
+
+  For the evaluation of a real literal with expected type having a Real_Literal
+  aspect specified ...
+
+Tucker tried to save some wording here, but I don't think the result is 
+particularly clear (one could easily read these as one single rule, from your 
+various gripes it appears that you did that), and two shorter sentences (even 
+if very repetitive) would be better than one longer one.
+
+This seems like a clear editorial review correction, if you want to request it.
+
+>Remember also that a key goal of Ada has always been that programs should
+>be easy to maintain by someone other than the author. Perhaps we need some 
+>mark to indicate that the literal has come via an aspect.
+
+No, that would destroy the purpose (to make the use of user-defined types the 
+same as the use of built-in types). Ideally, one would get rid of the built-in
+types altogether and define everything in packages using these aspects 
+(literals, indexing, de-reference, iterators, and so on).
+
+>We might write
+>   BI: Big_Integer := [-123456];
+
+The thing is square brackets is an array/container aggregate in Ada 2020.
+Supporting this syntax for literals would destroy the critical reason for 
+introducing the square bracket syntax for aggregates in the first place: the 
+ability to write single-valued aggregates in a natural way.
+
+So you need a different syntax.
+
+...
+
+> 1. Do nothing, leave it as it is. There is a risk that old John will 
+> resign from the ARG and not review anything else ever, ever! A bit 
+> unlikely since one supposes that he has to update his book. But he is 
+> very grumpy.
+
+I don't think we will leave it *exactly* as it is, but I don't think there are
+going to be major changes. I had some other thoughts, but they are best kept 
+to myself. :-)
+
+> 3. Do something more exciting as outlined above. But at least get rid 
+> of the Real_Literal and Integer_Literal aspects. Make it just Literal. 
+> Or if you must keep them, define exactly what the literal form is and 
+> provide a third aspect Literal for the ambitious user. Or maybe give 
+> the user the ability to add aspects so that Rational_Literal can be added.
+
+The reason for Real_Literal and Integer_Literal being separate was discussed 
+above. There is a third aspect, String_Literal (see AI12-0295-1, which you 
+haven't reviewed yet). It was split out because people wanted to vote 
+separately on the different aspects.
+
+Since these things are tied to the lexical structure of the program, adding 
+something more is complicated. And it is likely that an ambitious user could 
+use String_Literal for the sorts of suggestions that you have.
+
+> 4. Do not confuse rational numbers with a means of providing highly 
+> accurate real arithmetic. Define Big_Float or Big_Real. Preferably
+Big_Real.
+
+Ah, here we have an actionable suggestion. One has to use rational numbers to 
+*implement* accurate real arithmetic, but one does not have to *present* it 
+that way.
+
+Would you be happier if we renamed the current package and types to "Big_Real" 
+(no other changes)? This a change I could get behind, as I don't think anyone 
+really wants rational numbers (certainly not enough people to justify a 
+standard package), but lots of people want more accurate real numbers. Our 
+compiler's package calls these things "Univ_Real" (short for universal_real); 
+there's no sign of rational until you look under the covers.
+
+>To provide rationals is so easy that it hardly merits being in the language. 
+>But if it is, provide it as a separate item and do it properly.
+
+It's not remotely easy (to do correctly and efficiently). One has to reduce 
+the rationals frequently in order to avoid unbounded memory usage -- but you 
+can't do that after every operation because it is too expensive. In any case, 
+rationals are a rare need that doesn't need to be in the language per-se.
+
+Of course, someone could use the "Big_Real" package for rational math, (the 
+operations still all being there) but it wouldn't be presented that way.
+
+>Whatever is done, correct the phrase arbitrary-precision rationals from A.5.5. 
+>Rationals are always precise.
+
+Should say "arbitrary-precision reals", of course. That's what people 
+want/understand.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Thursday, February  7, 2019   9:05 PM
+
+I understand some of your concerns, John, but I also have experience with 
+supporting the use literals with user-defined types much as we have proposed, 
+and it is extremely valuable.  I also think the use of the term "Big_Rational" 
+has set you on edge, and I would agree with Randy that we should change these 
+to "Big_Real" to avoid the confusion.  If they are really viewed externally 
+as rationals, then you are right that the correct syntax for defining one 
+would be "N / M" where N and M are integer literals.  Instead, they are 
+intended to be used for arbitrary-precision real values, as is needed, say, 
+for your average Ada compiler front end.
+
+The point of AI-249 is not to support odd-ball syntaxes for literals, but 
+rather to allow the *existing* syntax for numeric literals to be used with 
+private types.  If the AI made you think that users were being given the 
+opportunity to invent some new kind of syntax for literals, it definitely 
+needs to be clarified.  The first thing to change is the !subject -- instead 
+of "user-defined numeric literals" it should be "numeric literals for 
+user-defined types."  And we should use that terminology throughout, rather 
+than ever saying "user-defined literals."  We really are not supporting that 
+in this AI.
+
+****************************************************************
+
+From: John Barnes
+Sent: Tuesday, February 12, 2019   9:27 AM
+
+Changing the title of 249 as you suggest would help a lot. I completely 
+misunderstood the purpose.
+
+And making it Big_Real would be excellent. Don't call them rationals 
+externally. That was the big mistake which as you say set me on edge.
+
+Make such changes and then  I can go to my grave in peace.  (well apart from 
+anonymous access types of course)
+
+So at the bottom of the problem is that the rationale for these AIs was not 
+clearly stated.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, February 12, 2019  11:08 AM
+
+> And making it Big_Real would be excellent.
+
+Why on earth would we call something a "real"
+if it can't represent irrational numbers such as square root of 2?
+
+As for literals, you want to be able to say things like:
+
+    X := 1/3;
+
+where X is a Big_Rat.  And you CAN say that.  I don't see why it makes any
+difference that the RM doesn't call that notation a "literal".  You can 
+think of it as a "literal" notation if you like.
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Tuesday, February 12, 2019   11:16 AM
+
+> Why on earth would we call something a "real"
+> if it can't represent irrational numbers such as square root of 2?
+
+Because since FORTRAN-2, it is a tradition to have the false advertisement 
+of calling "Real" a finite number of values from a bounded segment of the 
+rationals...
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February 12, 2019   11:25 AM
+
+>> And making it Big_Real would be excellent.
+> 
+> Why on earth would we call something a "real"
+> if it can't represent irrational numbers such as square root of 2?
+
+Well Ada has "universal-real" and it has the same problem.  In the context
+of Ada, I think Big_Real would be a reasonable name.  I agree in a wider 
+context, it could be misleading.
+
+> As for literals, you want to be able to say things like:
+> 
+>    X := 1/3;
+> 
+> where X is a Big_Rat.  And you CAN say that.  I don't see why it makes 
+> any difference that the RM doesn't call that notation a "literal".  
+> You can think of it as a "literal" notation if you like.
+
+It is worth pointing out that we do include in the "big-num" AI a "/" operator 
+that takes two (big) integers and produces a Big_R...  We also have a "/" that 
+takes 2 Big_Rs and produces another Big_R.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, February 12, 2019  11:31 AM
+
+> Why on earth would we call something a "real"
+> if it can't represent irrational numbers such as square root of 2?
+> 
+> As for literals, you want to be able to say things like:
+> 
+>      X := 1/3;
+> 
+> where X is a Big_Rat.  And you CAN say that.  I don't see why it makes 
+> any difference that the RM doesn't call that notation a "literal".  
+> You can think of it as a "literal" notation if you like.
+
+I agree with Bob.
+
+And don't forget that we have
+   function Numerator (Arg : Big_Rational) return Big_Integer;
+   function Denominator (Arg : Big_Rational) return Big_Positive ... ; which, 
+to me, strongly suggests that we are talking about rationals here.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February 12, 2019   3:15 PM
+
+You are confusing implementation with intended use. Conservatively, 95% of 
+users of this package are interested in getting exact real math, as in static 
+universal real calculations. They probably care little about the 
+implementation technique. I know I find the use of rationals in our universal 
+math package more annoying that useful. For that large subset of users, they 
+want "Big_Real" and could care less about rational anything.
+
+Note that Big_Real usage is the justification for supporting real literals 
+with the package. I agree with John in the sense that 0.0 makes no sense as a 
+rational number. But of course it is completely sensible for a Big_Real 
+number.
+
+The number of users that actually would want a rational number package is 
+small enough that we couldn't justify spending any time on standardizing it.
+
+It would make perfect sense to scrub this package of the operations which 
+expose a rational implementation, and literally make it a Big_Real package.
+But the implementation still would have to be using rationals. 
+
+There's no need to expose the rational implementation for most users, but it's 
+also harmless to do so for that <5% that actually care for some reason (and it 
+adds a bit of utility to the package). It's very much like Claw in this 
+regard: Claw has a handle interface which lets one access the underlying 
+Windows handles. But hardly anyone should ever need that (I've never used it, 
+for instance); it just exists for that rare user that has a need.
+
+One thing I would suggest is to place any of the operations that expose the 
+implementation dead last in the package (there shouldn't be many), so that the 
+typical user doesn't have to wade through irrelevant junk to get to the meat.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, February 12, 2019   6:13 PM
+
+> Well Ada has "universal-real" and it has the same problem.  In the context 
+> of Ada, I think Big_Real would be a reasonable name.
+
+I'd still prefer Big_Rational, but I agree that what you are saying makes 
+sense.
+
+Ada, for example, defines a type Integer rather than Bounded_Integer even 
+though the notion of Integer'Last is mathematically somewhat dubious.
+
+I can live with Big_Real.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent