CVS difference for 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