Just a thought, could you modify the behaviour of =
with a prefix, e.g. (approx 1 = 1.0)
(could perhaps get messy).
@rgchris made this suggestion 7 years ago.
It looked kind of neat, but I didn't see any real way to do it.
In The Isotopic Era
You Might Sort Of Do It
This can be made to work IF you are comparing values where the baseline result can be a raised error.
Something like:
>> 1 = 1.0
** (Raised) Error: Different-typed numeric values are only approximately equal
So you'd be able to have APPROX be a defuser for that specific error ID, and turn it into an ~okay~.
>> approx 1 = 1.0
== ~okay~ ; anti
Where this wouldn't work would be if the baseline response was falsey, e.g.
>> 1.000000001 = 1.000000000
== ~null~ ; anti
Hence the only way this would work out would be if you were willing to make that a raised error, forcing people to modify with something like EXACT
>> 1.000000001 = 1.000000000
** (Raised) Error: Numeric values very close, use EXACT or APPROX
>> exact 1.000000001 = 1.000000000
== ~null~ ; anti
>> approx 1.000000001 = 1.000000000
== ~okay~ ; anti
Is Making Close Compares Raise An Error A Practical Default?
Maybe. But it couldn't be just close compares that raised an error, it would be all floating point EQUAL? tests
See... there is a school of thought saying that plain equality tests shouldn't work on floating point numbers at all. You should only use SAME? to see if they're the exact same bit pattern, or comparison with some tolerance level.
Comparing Floating Point Numbers, 2012 Edition | Random ASCII – tech blog of Bruce Dawson
If we were to buck the norms, we could do this very bizarre thing where doing equality comparisons returned a raised error that embedded the exact difference in the error. (Actually, it would probably have to embed the compared numbers themselves, because as the article points out...the specific magnitudes affect the ideal choices for epsilon.)
APPROX(IMATELY) might use some common epsilon by default, but let you be more specific and act on the amount specified in the error.
This is a wacky idea that would let us help educate people on the innate perils of using equality on floating point numbers, while still letting people use the = operator on floating point numbers.
I can't say I hate it. It's... interesting.
But it propagates the concern to things like [foo 1.0] = [foo 1.0]
... if we say you can't do floating point comparisons without an approximation, then the moment you have two abstract blocks that want to compare it will trigger the raised error. And if the error involves an epsilon, how are you going to get the epsilon for all the floating point values in the block. You would have to compare the blocks in their entirety and find the "largest effective epsilon" somehow, and raise the error based on that.
Not impossible--and you have to compare the blocks in their entirety anyway in order to say they were equal--but wild. If we say the mechanic stops applying when you're comparing blocks, that gives echoes of the historical gap in behavior between comparing individual elements and then comparing them when they're in blocks--which I pointed out as bad mojo.
Anyway... one of many things to think about.