Open coke opened 4 months ago
I'm on vacation, and can't yet give this full attention, but Raku's DBZ, successes, failures, DBZ exceptions, ....
[please can you point to the source and I would be happy to try and grok the intent if I can]
for a long time IEEE P754 has given us valid values for the results of DBZ these were provided to allow pipelined vector FPU ops to succeed (even if an interim result was Inf or NaN) raku, uniquely [afaik], seeks to bridge this idea with Rats which can have a 0 denominator unless collapsed eg into a Str
following raiph's pointer to the docs on ZBRs, I see that this is OK:
say <1/0>.Num; # OUTPUT: «Infâ€Â»
say <-1/0>.Num; # OUTPUT: «-Infâ€Â»
say <0/0>.Num; # OUTPUT: «NaNâ€Â»
say Inf.Rat.nude; # OUTPUT: «(1 0)â€Â»
yet this is an error:
say <1/0>;
# Attempt to divide by zero when coercing Rational to Str in ...
my guess on the error attributes is:
div
, /
, .Str
(yes stringifying a Rat will try to print eg. a decimal)You can find all the instances (though you'll have to look at the source because many of these are part of a multi-line invocation) with
$ cd rakudo
$ ack 'X::Numeric::DivideByZero' src
numerator
is the numerator (only ever specified with using
). using
is typically the operator that was called (e.g. div
). There's no need to specify the denominator... because it's 0
.
details
is just plain text describing the situation, e.g.:
when calling .$what on Rational
when coercing Rational to Str
There is nothing in the current usage of rakudo or roast that requires details
over the numerator
/using
combo. Both of the examples above are easily translatable (esp. since using
is just free text)
There is no tie in to the CPU/FPU operations here.
s/ack/rak/
?? :-)
@coke thanks for clarifying my guess - looks like the info I guessed at is split between the using
and details
field (as you say no need for denominator - red face)
Based on this, I see no issue in keeping the fields as they are since both the using
(ie the operator) and the details
(ie when doing what) seem useful for debugging. The ZBRs are a quite thorny and unique(?) to raku so for me at least finding any extra hint is very valuable to work out what is happening.
On the FPU, apologies if I did not explain myself carefully, but the situation I wanted to clarify (at least to my own satisfaction) is that where this is a thing:
say <1/0>.Num; # OUTPUT: «Infâ€Â»
say <1/0>.Num.WHAT; # OUTPUT: «(Num)â€Â»
And this (although you can't make a string from it):
say <1/0>.Num.Rat.WHAT; # OUTPUT: «(Rat)â€Â»
Then, from a raku coder POV a valid mental model is that this is a divide by zero "non-failure" aka a ZBR that is made by creating a Inf (ie. by coercing a ZBR to an IEEE P754 Inf in the FPU since Num s are doubles) and then coercing it back to a Rat which as a construct of Ints lives in the CPU.
And I can make the identical thing via an FPU overflow like this:
say 1.7976931348623157e309; # OUTPUT: «Infâ€Â»
say 1.7976931348623157e309 === <1/0>.Num; # OUTPUT: «Trueâ€Â»
My point is that when you have done a bunch of P754 coding then it is most natural to think of Inf (aka the result of a DBZ op) as a creature of the FPU. This is the design of raku Num and the cool thing is the "interop" between Num and Rat - but also a source of potential complexity around DBZ behaviours.
So, obviously this would work too:
say (1e0/0e0).Rat; # OUTPUT: «Attempt to divide 1 by zero using /â€Â»...
.oO Realises that raku still supports DBZ exceptions in the FPU. Probably have to monkey with the compiler directives to put FPU in the "don't raise exception" mode atm. Would be nice to have that control on the same footing as eg my $*RAT-OVERFLOW
one day.
It took me a while to realise that this Failure is from an FPU exception so maybe the details
field could mention that? At least if not for now, then maybe this is the kind of nuanced message that could be put in details
in future.
While roast only seems to check the type of the exception, current rakudo has 3 attributes:
Checking where the exception is thrown by rakudo, it seems to either be a numerator/using pair, the single attribute details, or nothing. We should be consistent in usage and probably select
numerator
andusing
, removedetails
, and ensure that wherever we throw the exception, we include the information.Because there is no testing of these attributes in roast, we could do this as an implementation detail in existing rakudo, but I would recommend implementing it as a 6.e feature and then testing the attributes in roast for 6.e