!standard A.5.4(4) 20-02-05 AI12-0362-1/01
!class Amendment 20-02-05
!status work item 20-02-05
!status received 19-11-12
!priority Low
!difficulty Easy
!subject Floor and other rounding attributes for fixed point types
!summary
Floor, Ceiling, and rounding attributes are supported for fixed point types.
!problem
There is a growing interest in fixed-point with the emergence of machine
learning and GPUs. It is nice if an algorithm can be moved between fixed
and float without signifiant re-engineering. However, the attributes Floor
Ceiling, Rounding, Unbiased_Rounding, Machine_Rounding, and Truncation are
missing for fixed point types. This forces unnecessary conversions to
floating point types, which can themselves introduce rounding effects.
!proposal
(See Summary.)
!wording
A fixed point type *has integral values* if its Small value is an integral
value or if a multiple of the Small value is an integral value. A generic
formal type is defined to have integral values.
Add after A.5.4(4):
The following primitive function attributes are defined for any subtype S of a
fixed point type T that has integral values:
S'Ceiling
S'Ceiling denotes a function with the following specification:
function S'Ceiling (X : T)
return T
The function yields the value *Ceiling(X)*, that is, the smallest (most negative)
integral value greater than or equal to X. If T is a generic formal type,
S'Ceiling raises Program_Error if the actual subtype does not have integral values.
S'Floor
S'Floor denotes a function with the following specification:
function S'Floor (X : T)
return T
The function yields the value *Floor(X)*, that is, the largest (most positive)
integral value less than or equal to X.
S'Rounding
S'Rounding denotes a function with the following specification:
function S'Rounding (X : T)
return T
The function yields the integral value nearest to X, rounding away from zero
if X lies exactly halfway between two integers.
S'Unbiased_Rounding
S'Unbiased_Rounding denotes a function with the following specification:
function S'Unbiased_Rounding (X : T)
return T
The function yields the integral value nearest to X, rounding toward the even
integer if X lies exactly halfway between two integers.
S'Machine_Rounding
S'Machine_Rounding denotes a function with the following specification:
function S'Machine_Rounding (X : T)
return T
The function yields the integral value nearest to X. If X lies exactly halfway
between two integers, one of those integers is returned, but which of them is
returned is unspecified. This function provides access to the rounding behavior
which is most efficient on the target processor.
AARM Discussion: We leave the rounding unspecified, so that users cannot
depend on a particular rounding. This attribute is intended for use in cases
where the particular rounding chosen is irrelevant. If there is a need to know
which way values halfway between two integers are rounded, one of the other
rounding attributes should be used.
S'Truncation
S'Truncation denotes a function with the following specification:
function S'Truncation (X : T)
return T
The function yields the value Ceiling(X) when X is negative, and Floor(X)
otherwise.
[Editor's note: The following is not indented like the above; it applies to
all of these attribute functions.]
For all of these attributes, if T is a generic formal type,
S'Floor raises Program_Error if the actual subtype does not have integral
values.
AARM To Be Honest: The check that the type of the prefix has integral values
is considered a Legality Rule.
AARM Reason: The rules here for generic formal types are classic
assume-the-best rules for legality checking; the check is redone in the
specification of the instance. We use a runtime check on the
actual subtype to avoid assume-the-worst in generic bodies (which would
mean the attributes could never be used in a generic body on a formal
subtype). For implementations that expand generic bodies, it is always
possible to provide a warning about the exception being raised.
!discussion
We only allow these attributes on types that have integral values in order
to avoid nonsense results for types that cannot exactly represent integers.
For instance, for a type defined:
type Foobar is delta 0.7 range 0.0 .. 7.0 with Small => 0.7;
Foobar'Floor(1.4) = 0.7 (as 0.7 is the nearest model number to 1.0). But these
functions are defined to return "integral values", and it takes a strong
imagination to see 0.7 as an integral value.
Worse, in the worst case, this issue can destroy one of the primary purposes
of the rounding attributes: to specify how a value gets rounded to an integer
value.
type Horrible is delta 2.5 range -10.0 .. 10.0 with Small => 2.5;
Obj : Horrible := 2.5;
A : Integer := Integer(Horrible'Floor(Obj));
The purpose of this expression is to ensure that 2.5 rounds down so that A = 2.
But here, the result of Horrible'Floor(Obj) would be 2.5, meaning
that the default rounding of the integer conversion would be used - which is
defined by 4.6(33) as round away from zero. Thus A will be 3, even though the
user carefully wrote the expression needed to prevent that.
Note that if the Small is itself an integer, these attributes are identity
functions, so these can be allowed.
!ASIS
No change is needed.
!ACATS test
ACATS B- and C-Tests are needed to check proper definition and operation of
the attributes.
!appendix
From: Jean-Pierre Rosen
Sent: Tuesday, November 12, 2019 2:59 AM
The question came recently on fr.comp.lang.ada as to why there was no 'Floor
attribute for fixed points... and I could not find any reason.
Is it an omission, not enough value, possible candidate for 202X?
****************************************************************
From: Tucker Taft
Sent: Tuesday, November 12, 2019 7:50 AM
I would agree with making the attributes as much as possible independent of
whether a real type is fixed or float. There seems to be a growing interest
in fixed-point with the emergence of machine learning and GPUs. It is nice
if an algorithm can be moved between fixed and float without signifiant
re-engineering.
****************************************************************
From: Randy Brukardt
Sent: Tuesday, November 12, 2019 3:10 PM
One problem with defining Floor and Ceiling for fixed point is dealing with
the corner case where some integral values cannot be represented in the fixed
point type. We'd have to figure out how that works.
There's two forms of this issue:
type Tiny_Fixed is delta 0.125 range 0.0 .. 0.5
with Small => 0.125;
Here, Ceiling of any Tiny_Fixed value would be out of range. Probably raising
Constraint_Error is OK here.
If the small is tiny enough, even the base type may not have an integer value
other than 0.0.
(The float version has this issue as well, and it doesn't seem to be defined
what happens. Specifically, T'Ceiling(T'Base'Last) potentially is an issue if
T'Base'Last is not an integer. Probably a To Be Honest is good enough for
floats, since it doesn't happen in IEEE math.)
One could have a similar probem for Floor with an appropriate range.
The second case is the real problem:
type Weird_Fixed is delta 0.7 range 0.0 .. 70.0
with Small => 0.7;
What is Weird_Fixed'Floor(2.1)? Explain your answer. :-)
Even though such a type is arguably a pathology, we need to have some sort of
definition for it. (One possibility is to make 'Floor and 'Ceiling only
available for Small values such that Small*N = 1.0 for some integer N. To
avoid a contract model problem, they'd have to raise Program_Error in a
generic if the Small is bad, even if illegal elsewhere.)
I suspect this issue is why they're not defined, but since they're useful, it
probably is worth working harder to define them rather than letting the
existence of a pathology prevent that.
****************************************************************
From: Tucker Taft
Sent: Tuesday, November 12, 2019 3:20 PM
Program_Error for deltas that are not divisible into 1.0 might be one choice.
****************************************************************
From: Randy Brukardt
Sent: Tuesday, November 12, 2019 3:29 PM
That's what I said (Small, not Delta, though - Delta's are meaningless
semantically), even if I couldn't figure out how to put it into English.
****************************************************************
From: Jean-Pierre Rosen
Sent: Tuesday, November 12, 2019 3:38 PM
> The second case is the real problem:
>
> type Weird_Fixed is delta 0.7 range 0.0 .. 70.0
> with Small => 0.7;
>
> What is Weird_Fixed'Floor(2.1)? Explain your answer. :-)
It's 2.1.
The model should be that the floor is Universal_Integer, then converted back
to the type. Simple to explain, works with every case.
Interestingly enough, the OP suggested that 'Floor would return
Universal_Integer instead of the original type. Another possibility, avoids
many problems, but would not ease switching back and forth between fixed
points and floating points.
****************************************************************
From: Tucker Taft
Sent: Tuesday, November 12, 2019 3:48 PM
But the conversion from Univ Integer to a fixed point type is not fully
defined if between two multiples of small, so we would need to define which
one to choose. The whole idea is a bit weird if the result is not an integer
when done, so I think an unconditional Program_Error might be a better result
(which would generally be detected at compile-time except in shared-generic
situations).
****************************************************************
From: Jean-Pierre Rosen
Sent: Thursday, December 5, 2019 4:11 AM
I don't think that raising Program_Error for a simple mathematical operation
is a good idea. Why should it be different from an explicit conversion?
I am willing to write the AI if everybody agrees that it is worth a try.
****************************************************************
From: Tucker Taft
Sent: Thursday, December 5, 2019 9:17 AM
Go for it!
****************************************************************
From: Jean-Pierre Rosen
Sent: Thursday, December 5, 2019 8:22 AM
Here it is...
!standard A.5.3 <19-12-05> AI12-000X-1/01
!class Amendment
!status work item
!status received
!priority Medium
!difficulty Easy
!subject
'Floor and 'Ceiling for fixed point types.
!summary
The 'Floor and 'Ceiling attributes are defined for every
fixed point type.
!problem
Floating point types have 'Floor and 'Ceiling attributes.
These are useful functions for all real calculations, however
they are not provided for fixed point types. In order to avoid
unnecessary conversions to an intermediate floating point type,
it would be useful to provide them for fixed point types.
!proposal
S'Floor denotes a function with the following specification:
function S'Floor (X : T)
return T
The function yields the value Floor(X), i.e., the result of
converting to S the largest (most positive) integral value less than
or equal to X.
S'Ceiling denotes a function with the following specification:
function S'Ceiling (X : T)
return T
The function yields the value Ceiling(X), i.e., the result of
converting to S the smallest (most negative) integral value greater
than or equal to X.
!wording
!discussion
There is a special difficulty for 'Floor and 'Ceiling on fixed points,
since integer values are not necessarily model numbers of the type.
Therefore, these attributes are defined as the result of the
conversion of the (universal integer) value of the mathematical Floor
and Ceiling to the fixed point type, following normal rules for
conversion.
Another option would be to raise an exception if the result cannot be
represented as an integer value, but it would be presumably less
user-friendly, since no other operation raises an exception when the
result cannot be exactly represented.
!ASIS
No change is needed
!ACATS test
An ACATS C-Tests is needed to check the proper operation of the
attributes.
****************************************************************
From: Jean-Pierre Rosen
Sent: Friday, December 6, 2019 8:04 PM
> > But the conversion from Univ Integer to a fixed point type is not
> > fully defined if between two multiples of small, so we would need to
> > define which one to choose. The whole idea is a bit weird if the
> > result is not an integer when done, so I think an unconditional
> > Program_Error might be a better result (which would generally be
> > detected at compile-time except in shared-generic situations).
> I don't think that raising Program_Error for a simple mathematical
> operation is a good idea.
I agree. For types where it is possible, it should be illegal. For generic
formal types (only), it needs to raise Program_Error to avoid contract
problems.
> Why should it be
> different from an explicit conversion?
Not quite sure what "explicit conversion" you are talking about. But for an
Integer to fixed point conversion, the "contract" is that the result is the
closest value to the operand. For the Floor and Ceiling attributes, the
contract is that the result is the appropriate *Integer* value for the
operand. If an integer value cannot be delivered in most cases, then the
contract cannot be met for those cases, and the operation is misleading at
best.
If a multiple of the Small is not an integer, then the above is true, and the
operation should not be allowed. My preference is for the operation to be
illegal for non-formal types in that case, to avoid the possibility of someone
failing to notice the problem until testing or worse, deployment.
This case is likely the reason that these operations were not provided in the
first place, but that seems like a baby with the bathwater situation (types
for which this is a problem are quite unusual).
> I am willing to write the AI if everybody agrees that it is worth a
> try.
I was going to do it next week, but I don't mind someone else doing work for
me. :-)
I'm not interested in a version that allows pathological results that violate
the contract of the operation, however.
****************************************************************
From: Jean-Pierre Rosen
Sent: Saturday, December 7, 2019 1:02 AM
>> Why should it be
>> different from an explicit conversion?
> Not quite sure what "explicit conversion" you are talking about.
The explicit conversion of the universal integer representing the floor to the
fixed point type.
> But for an
> Integer to fixed point conversion, the "contract" is that the result
> is the closest value to the operand. For the Floor and Ceiling
> attributes, the contract is that the result is the appropriate
> *Integer* value for the operand. If an integer value cannot be
> delivered in most cases, then the contract cannot be met for those
> cases, and the operation is misleading at best.
No, you miss Ada's (and Brown's) model of real arithmetic. A real value stands
for a small interval, like an approximate number. Therefore it makes sense to
return the value that represents an interval that includes the (mathematical)
Floor/Ceiling, even if its associated model number is not integer.
That behaviour is consistent with the model of arithmetic and avoids all
exception and contract model problems. A note would certainly be welcome,
though.
This should not surprise the user more than the following example (extracted
from one of my slides about real arithmetics):
procedure Test_Fix is
type Fix is delta 0.1 range -10.0 .. 10.0;
X : Fix := 0.4;
Y : Fix;
begin
Y := X + X + X; -- prints as 1.1
end Test_Fix;
****************************************************************
From: Randy Brukardt
Sent: Sunday, December 8, 2019 5:23 PM
> >> Why should it be
> >> different from an explicit conversion?
> > Not quite sure what "explicit conversion" you are talking about.
> The explicit conversion of the universal integer representing the
> floor to the fixed point type.
You can't directly write such a conversion in Ada for a non-static expression.
Any conversion you can write has to include some explicit discrete type and
that type brings the possibility of exceptions.
> > But for an
> > Integer to fixed point conversion, the "contract" is that the result
> > is the closest value to the operand. For the Floor and Ceiling
> > attributes, the contract is that the result is the appropriate
> > *Integer* value for the operand. If an integer value cannot be
> > delivered in most cases, then the contract cannot be met for those
> > cases, and the operation is misleading at best.
> No, you miss Ada's (and Brown's) model of real arithmetic.
Not at all.
> A real value stands for a small interval, like an approximate
> number.
Surely. But one of the reasons for using an integral value is that it avoids
that nonsense; for all sane types, an integral value is a model number and
thus the interval is just that exact value.
> Therefore it makes sense to return the value that
> represents an interval that includes the (mathematical)
> Floor/Ceiling, even if its associated model number is not integer.
No, that doesn't make sense. One of the important uses of attributes like
'Floor and 'Ceiling is to ensure that there is a unique value (*not* an
interval) for the result. If you allow intervals from the result, then you
are not getting that behavior. And you are bringing rounding effects into an
operation that is intended to *eliminate* such effects.
Fixed point 'Floor can be implemented with all integer operations so long as
the scale factor (the inverse of the Small of the type) is an integer. Then
'Floor is (ignoring signs for the moment):
Fixed'Floor(Expr) := Expr - (Expr mod Fixed'Scale);
You can also implement 'Floor easily if the Small is an integer, in that
case 'Floor is a no-op.
Otherwise, through, the only sensible way to implement 'Floor would seem to
be:
Fixed (Some_Float'Floor (Some_Float(Expr) * Fixed'Small))
and that brings in the possibility of rounding errors and other nonsense.
If someone really wants this latter expression, they can write it themselves
and make all of the dangers obvious. It doesn't make sense to hide this mess
behind an attribute that looks simple and accurate.
These sorts of cases are rare, and I don't like the fact that we've thrown
out the baby with the bathwater by not supporting this attribute in the
common case where it makes sense and has a reasonable implementation. But
forcing implementations to support a nonsense implementation which almost
certainly is not going to give the result that the user wants is not helping
anyone. Moreover, given the rare use of these things, it's likely that
implementers would cut corners here and only use the bad implementation.
(*I* surely would do that here; I don't care much about fixed point and
don't have much customer usage.)
I don't see any reason to make implementers spend effort on a bad
implementation simply so that some rarely-used types can have attributes
that doesn't even serve their intended purpose for such types. Let's have
them spend all of their effort on a good implementation (only).
> That behaviour is consistent with the model of arithmetic and
> avoids all exception and contract model problems. A note
> would certainly be welcome, though.
>
> This should not surprise the user more than the following
> example (extracted from one of my slides about real arithmetics):
>
> procedure Test_Fix is
> type Fix is delta 0.1 range -10.0 .. 10.0;
> X : Fix := 0.4;
> Y : Fix;
> begin
> Y := X + X + X; -- prints as 1.1
> end Test_Fix;
This surprised me and I know the fixed point model. Eventually I realized
that you had intentionally violated rule #1 of fixed point types -- *always*
specify the small.
Ada made a serious mistake by not making the Small = the Delta initially,
and the only reasonable workaround to that is to always specify the Small so
you get want you mean and not some nonsense like the above. I presume
AdaControl has such a rule, and I doubt that there are any serious users of
fixed point that don't follow it. Otherwise, *every* use of fixed point is a
surprise.
****************************************************************
From: Jean-Pierre Rosen
Sent: Monday, December 9, 2019 10:04 AM
> You can't directly write such a conversion in Ada for a non-static
> expression. Any conversion you can write has to include some explicit
> discrete type and that type brings the possibility of exceptions.
Only in the case of an overflow, which is not what we are talking about.
...
> Surely. But one of the reasons for using an integral value is that it
> avoids that nonsense; for all sane types, an integral value is a model
> number and thus the interval is just that exact value.
I agree that a fixed point type where integer values are not model number may
not be considered a "sane" type. But that's what we are talking about;
otherwise, there is no problem.
>> Therefore it makes sense to return the value that represents an
>> interval that includes the (mathematical) Floor/Ceiling, even if its
>> associated model number is not integer.
>
> No, that doesn't make sense. One of the important uses of attributes
> like 'Floor and 'Ceiling is to ensure that there is a unique value
> (*not* an interval) for the result. If you allow intervals from the result,
> then you are not getting that behavior. And you are bringing rounding
> effects into an operation that is intended to *eliminate* such effects.
My proposal doesn't allow intervals: it requires the result of the conversion
of the mathematical value to the fixed point type. I don't even think it is
possible for the mathematical value to be exactly half way between two model
numbers without being itself a model number. [proof needed]. (if 0.5 and 1.5
are model numbers, then certainly 1.0 is. 2.0 and 4.0 could be model numbers
and not 3.0, but then there would be no model number whose floor is 3.0).
> Fixed point 'Floor can be implemented with all integer operations so
> long as the scale factor (the inverse of the Small of the type) is an
> integer. Then 'Floor is (ignoring signs for the moment):
>
> Fixed'Floor(Expr) := Expr - (Expr mod Fixed'Scale);
>
> You can also implement 'Floor easily if the Small is an integer, in
> that case 'Floor is a no-op.
>
> Otherwise, through, the only sensible way to implement 'Floor would
> seem to
> be:
>
> Fixed (Some_Float'Floor (Some_Float(Expr) * Fixed'Small))
>
> and that brings in the possibility of rounding errors and other nonsense.
You are talking here about implementation, which is a different issue.
However, I don't see why it should be different from a conversion to an
integer type, which has always been available.
> If someone really wants this latter expression, they can write it
> themselves and make all of the dangers obvious. It doesn't make sense
> to hide this mess behind an attribute that looks simple and accurate.
>
> These sorts of cases are rare, and I don't like the fact that we've
> thrown out the baby with the bathwater by not supporting this
> attribute in the common case where it makes sense and has a reasonable
> implementation. But forcing implementations to support a nonsense
> implementation which almost certainly is not going to give the result
> that the user wants is not helping anyone. Moreover, given the rare
> use of these things, it's likely that implementers would cut corners here
> and only use the bad implementation.
> (*I* surely would do that here; I don't care much about fixed point
> and don't have much customer usage.)
Convert to some integer type, then convert back to the fixed point type (with
some extra care to get the right integer). No need to use floats.
...
>> This should not surprise the user more than the following example
>> (extracted from one of my slides about real arithmetics):
>>
>> procedure Test_Fix is
>> type Fix is delta 0.1 range -10.0 .. 10.0;
>> X : Fix := 0.4;
>> Y : Fix;
>> begin
>> Y := X + X + X; -- prints as 1.1
>> end Test_Fix;
>
> This surprised me and I know the fixed point model. Eventually I
> realized that you had intentionally violated rule #1 of fixed point
> types -- *always* specify the small.
There are two views of fixed point types: some kind of integer type whose
"step" happens to be different from 1, and the view of approximate numbers,
which is what most physicists need. Your remark is correct only in the first
case. A well behaved phycists would think (example above):
Y = 1.2 +- 0.3
and of course, 1.1 is well within expected range.
> Ada made a serious mistake by not making the Small = the Delta
> initially, and the only reasonable workaround to that is to always
> specify the Small so you get want you mean and not some nonsense like the
> above.
No nonsense, just a different use case.
> I presume
> AdaControl has such a rule, and I doubt that there are any serious
> users of fixed point that don't follow it.
check declarations (ordinary_fixed_type_no_small);
> Otherwise, *every* use of fixed point is a surprise.
... until you are taught how it works (which is true of many things).
****************************************************************
From: Randy Brukardt
Sent: Monday, December 9, 2019 8:26 PM
...
> > No, that doesn't make sense. One of the important uses of attributes
> > like 'Floor and 'Ceiling is to ensure that there is a unique value
> > (*not* an interval) for the result. If you allow intervals from the
> > result, then you are not getting that behavior. And you are bringing
rounding
> > effects into an operation that is intended to *eliminate* such effects.
> My proposal doesn't allow intervals: it requires the result of the
> conversion of the mathematical value to the fixed point type. I don't
> even think it is possible for the mathematical value to be exactly
> half way between two model numbers without being itself a model
> number.
> [proof needed]. (if 0.5 and 1.5 are model numbers, then certainly 1.0
> is. 2.0 and 4.0 could be model numbers and not 3.0, but then there
> would be no model number whose floor is 3.0).
Huh? Now you are suggesting rounding (by the "halfway" stuff") in an attribute
specifically designed to override any rounding with a specific answer. That
doubles the nonsense!
...
> > and that brings in the possibility of rounding errors and other nonsense.
> You are talking here about implementation, which is a different issue.
Not at all. The nonsense definition also leads to implementation expense.
> However, I don't see why it should be different from a conversion to
> an integer type, which has always been available.
Conversion rounds, which is a very different operation. You can't use one to
implement the other in general.
Also, conversion also requires the use of floating point in general (or a
runtime big-real library). Since that implementation has to be available as
a fall-back, and no one can spend lots of time on a little-used feature, it
becomes the primary implementation. After all, one has to handle types like:
PI : constant := Ada.Numerics.PI;
type Radian is delta PI/180.0 range -2*PI .. 2*PI
with Small => PI/180.0;
Even a simpler type like the Small => 0.7 that we were talking about can be
problems to implement solely with integer math, as overflow is an ever-present
problem. Only some cases can be implemented that way, and which ones depend on
the Small and the range of the type. And there's at least 4 different patterns
that might work, depending on those values. It's too expensive except for the
most useful pattern.
The integer conversions probably shouldn't have been available for these silly
types, either, as they won't provide the intended results anyway.
Probably too late for that (compatibility).
...
> > Moreover, given the rare
> > use of these things, it's likely that implementers would cut corners
> > here and only use the bad implementation.
> > (*I* surely would do that here; I don't care much about fixed point
> > and don't have much customer usage.)
> Convert to some integer type, then convert back to the fixed point
> type (with some extra care to get the right integer).
> No need to use floats.
You have to use floats to convert to an integer in many of these cases (or a
runtime big-real library). And a conversion rounds here, which is definitely
not the Floor operation. For any of these types, converting to Integer will
guarantee the wrong answer some of the time.
...
> > This surprised me and I know the fixed point model. Eventually I
> > realized that you had intentionally violated rule #1 of fixed point
> > types -- *always* specify the small.
> There are two views of fixed point types: some kind of integer type
> whose "step" happens to be different from 1, and the view of
> approximate numbers, which is what most physicists need. Your remark
> is correct only in the first case. A well behaved phycists would think
> (example above):
> Y = 1.2 +- 0.3
> and of course, 1.1 is well within expected range.
Since Ada real math is interval math, one has to analyze the intervals in
order to know whether the error is really "+- 0.3". There's no way to know
that for certain, in particular because Ada only requires the "close result
set" for the results of operations on unusual small values.
In any case, there are very few programmers who know enough to use proper
error analysis on real math. Everyone one else "wings it" assuming usual
mathematics. (For instance, the original SPARK did not use an interval math
model, so it could "prove" all kinds of fallacies when it came to real
math.) When that mathematics isn't followed, people are going to be confused.
> > Ada made a serious mistake by not making the Small = the Delta
> > initially, and the only reasonable workaround to that is to always
> > specify the Small so you get want you mean and not some
> nonsense like the above.
> No nonsense, just a different use case.
Even in the use case you are postulating, you don't get +- 0.3 as the error
unless you specify the small. The actual error in each operation can be nearly
as much as 2*Small, so you could get as much as +- 0.375. (Probably not in
practice with these values and specific operations, but definitely with a mix
of runtime values.)
...
> > Otherwise, *every* use of fixed point is a surprise.
> >
> ... until you are taught how it works (which is true of many things).
Sorry, human factors engineering does not rely on training to avoid surprise.
(Boeing should have remembered that with the Max.) If something is designed in
a way that means you don't get what you intend nearly all of the time, that is
a surprise and it never goes away.
I've seen examples like this for 30+ years, and I'm still surprised by them
(I also remember that much about fixed point is a surprise, so I know to go
back to first principles). I think that is the definition of a badly designed
feature.
We're getting off-topic here, and in any case, I don't think either of us is
going to convince the other of anything. So it's probably getting close to
time to close this discussion.
This does reopen the question of whether we should be considering this idea
for Ada 202x at all. It is well past our deadline for new ideas, and if we are
going to take most people's new ideas and not consider them now (and that is
certainly the case), we have to be very careful about adding in our own. Steve
and I talked this over and thought that we could consider some very simple
improvements so long as they have consensus. This one initially appeared in
that category, but now that is looking less likely. Is it worth spending
meeting time on an idea that isn't even supposed to be on our work list to
solve this issue?
****************************************************************
From: Jean-Pierre Rosen
Sent: Tuesday, December 10, 2019 2:13 AM
> We're getting off-topic here, and in any case, I don't think either of
> us is going to convince the other of anything. So it's probably
> getting close to time to close this discussion.
Agreed
> This does reopen the question of whether we should be considering this
> idea for Ada 202x at all. It is well past our deadline for new ideas,
> and if we are going to take most people's new ideas and not consider
> them now (and that is certainly the case), we have to be very careful
> about adding in our own. Steve and I talked this over and thought that
> we could consider some very simple improvements so long as they have
> consensus. This one initially appeared in that category, but now that
> is looking less likely. Is it worth spending meeting time on an idea
> that isn't even supposed to be on our work list to solve this issue?
I propose to put it on the agenda, and then the group can vote it "stay alife"
or "no action" (or anything else).
****************************************************************
From: Arnaud Charlet
Sent: Tuesday, December 10, 2019 2:49 AM
> ... Is it worth spending meeting time on an idea
> that isn't even supposed to be on our work list to solve this issue?
No, I agree that it's not worth it and it's way too late for Ada 202x.
****************************************************************