Ease of FatRat construction

So, on #perl6 today tried using the numeric literal .3333333333333333333333333333333. (Warning: exact number of 3‘s may not match original example.) By the spec (as I understand it), this is a Num, because a Rat isn’t accurate enough to represent it. (Not that a Num is, mind you!)

And that got me to thinking: What if you really wanted a FatRat, so you actually got that exact number? Well, if you’re using Niecza (the only p6 to implement FatRat so far), the answer is FatRat.new(3333333333333333333333333333333, 10000000000000000000000000000000). IMO, that’s ridiculously awkward.

The spec may imply you can do it with ".3333333333333333333333333333333".FatRat. That at least avoids the problem of counting the zeros, but it’s still on the ugly side. Likewise FatRat.new(".3333333333333333333333333333333") is awkward. Still, we should certainly support at least one of these options.

I would like to propose again adding an F suffix to indicate a numeric literal should be a FatRat. I don’t think this is something that can reasonably be done with a postfix operator, because if you treat .3333333333333333333333333333333 like a normal numeric value and then try to FatRat it, you will lose the precision you want.

Just as a quick comparison, here’s a bit of the old endless pi code using the FatRat constructor:

sub unit() { LFT.new(q => FatRat.new(1, 1),
                     r => FatRat.new(0, 1),
                     s => FatRat.new(0, 1),
                     t => FatRat.new(1, 1)); }

I’m proposing we should be able to write that as

sub unit() { LFT.new(q => 1F,
                     r => 0F,
                     s => 0F,
                     t => 1F); }

Much shorter and much clearer. I think that’s a big win.

(Note: I’m in no way particularly attached to the letter “F” for this, that was just the first thing that came to mind.)


5 Responses to “Ease of FatRat construction”

  1. Moritz Says:

    I’d propose to make Rat literals automatically chose FatRat if they would otherwise lose precision.

    You could write the constructor as

    LFT.new(|{ q => 1, r => 0, s => 0, t => 0}».FatRat});

    Maybe some other literal form would be nice too, but I always felt that the type postfixes for number literals in C/C++ are the wrong approach (though I can’t really explain why).

  2. colomon Says:

    Choosing FatRat always needs to be explicit, IMO. That’s because once you’ve got one FatRat, every downstream result of math operations is also a FatRat, and suddenly the implicit FatRat means you’ve accidentally made all your math operations become hogs in time and space.

  3. heir Says:

    So… if not a postfix operator, why not a macro?

    • colomon Says:

      As far as I know, this certainly could be implemented by a macro once that functionality is available. It might even work now in Rakudo, though it would be useless there at the moment as Rakudo does not support FatRat yet.

  4. SMR Says:

    A postfix F feels too much like the postfix for a float literal in other languages (like Java). How about R instead?

    Regarding colomon’s comment, can a syntactic/literal postfix contain, say, a dot? Would “.R” be easy to use? Or would just make parsing insane? .3333.R ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: