Raku/old-design-docs

Should Rats auto-coerce to Ints when possible?

coke opened this issue · 5 comments

coke commented

Raised by the bug at https://rt.perl.org/rt3/Ticket/Display.html?id=78324

17:04 < moritz_> rakudo: say ~(64,32,16 ...^ Rat)
17:05 <+p6eval> rakudo 37eafa: OUTPUT«64 32 16␤»
17:05 < masak> eh?
17:05 < moritz_> it doesn't re-coerce to int
17:05 < moritz_> it calculates 8 as 1/2 * 16
17:05 < moritz_> which is a Rat

21:54 < [Coke]> r: say ~(64,32,16 ...^ Rat)
21:54 <+camelia> rakudo 8a0859: OUTPUT«64 32 16␤»
21:54 < TimToady> 16/2 is a Rat :)
21:56 < TimToady> n: say ~(64,32,16 ...^ Rat)
21:56 <+camelia> niecza v24-51-g009f999: OUTPUT«64 32 16␤»
21:56 < [Coke]> TimToady: that was the concensus, yes. Would you say that's
operating as intended, or should it be smarter?
21:56 < TimToady> well, the question is whether a Rat should auto-coerce itself
to an Int if it can
21:57 < TimToady> I don't know that we have any consensus on that

I think the question is rather if the sequence operator should coerce to Int if the previous list elements are Int and it can be done without loss of precision.

Moritz: for clarification, you're suggesting that with 720, 360, 180 ... * the sequence operator would produce Ints down to 45 and Rats after that?

It seems to me that (broadly speaking) there are three possible solutions here:

  1. Rat math auto-coerces to Int if the denominator is 1.
  2. The sequence operator auto-coerces Rat values to Int if the denominator is 1.
  3. Declaring that things are fine as they are.

Personally my inclination is to go with #3, based on the feeling that adding more auto-coercing magic makes naive use easier but makes full understanding harder.

Though this example does make me wonder if .nu and .de methods should be added to Int. That would give an easy and clear way to specify the sequence in question: 64, 32, 16 ... *.de != 1. (Admittedly, making special-case accessor methods more widely available appears to be my favorite trick of the moment...)

Note that it's .denominator now, not .de.

@pmichaud: yes, that would be my suggestion. However leaving things as-is would be acceptable for me too.

I'm against @colomon's 1., Rat math auto-coerces to Int if the denominator is 1, because then you'll get exceptions when you type variable as Rat.

So if we don't decide to leave things as is, my suggestion would be to introduce a new method like as-narrowest-type or so in the numeric types which returns a copy of the invocant coerced to the narrowest type that doesn't lead to loss of precision. So a Complex with imaginary part 0 would produce $c.re.as-narrowest-type, and a Rat would return an Int if the denominator is 1. Then the series operator could call that method on the item it generates.