Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Something that bugs me about the Numeric class hierarchy in Perl 6

by grondilu (Friar)
on Nov 24, 2015 at 08:16 UTC ( #1148483=perlmeditation: print w/replies, xml ) Need Help??

Hello Monks,

This is something that has bugged some times to times : I have the feeling that the class hierarchy for numeric types in Perl 6 is upside down.

Let me give you an example. The other day I wrote on rosetta code the following function to compute binomial coefficients:

sub infix:<choose> { [*] ($^n ... 0) Z/ 1 .. $^p } say 5 choose 3;

I was quite happy about it, until I realized that the output was of type Rat, not Int. So I had to make an explicit conversion:

sub infix:<choose> { ([*] ($^n ... 0) Z/ 1 .. $^p).Int }

That was a bit annoying. Frankly, I expect something like 10/5 to be an integer, not a rational. I mean, I know it is a rational, but it also is an integer. Because normally in math, all integers are rationals. Their denominator is just 1.

Things don't work like this in Perl 6. Numeric types are more about implementation than mathematics. Yet there is a feature in Perl 6 that could be used to make things work more like in math:

subset Int of Rat where [%%] *.nude;

If Int was defined as such, integers would be particular cases of rationals. In the same way, real numbers would be special cases of complex numbers:

subset Real of Complex where { $_ == .conj };

An other possibility would be:

role Int does Rational { method nude { self, 1 }; ... }

Or something like that, I don't know. Neither do I know if it would be possible or desirable to rewrite the whole Numeric hierarchy. Maybe it would not be worth the effort. But I do find it annoying that an Integer is not a Rat, or a Real not a Complex.

Replies are listed 'Best First'.
Re: Something that bugs me about the Numeric class hierarchy in Perl 6
by Laurent_R (Canon) on Nov 24, 2015 at 18:57 UTC
    Hum, this probably does not really answer your question, and I am not even sure I really understand your question, but it seems to me that the intermediate results are not always integers, but sometimes rats. So that when you multiply them, even if you end up with something looking like an integer, it has been computed as a rat.

    Removing the list product from your function to see the list of computed values:

    sub infix:<list_vals> { ($^n ... 0) Z/ 1 .. $^p } say 10 list_vals 3; # -> (10 4.5 2.666667) sub infix:<choose> { [*] ($^n ... 0) Z/ 1 .. $^p } say 10 choose 3; # -> 120 (rat)

      The intermediate results are indeed rats. And yes the result is a rat that looks like an integer. My point was that I wish there was no difference between a "rat that looks like an integer" and an actual integer. In other words, I wish integers were a special case of rats, because in math that's what they are, maybe not by definition, but at least by property : the set Z in included in the set Q. Thus my suggestion of using perl6's subset concept.

        I just noticed this discussion and it's a difference of opinion I've also had with the core P6 devs: integers and rats are the same. That being said, integer math should be much faster than rational math and I don't know how difficult it would be to special case the code for that.

        On the flip side, by restricting this behavior now, they wouldn't need to take it away later if it proved problematic. I expect that heavier usage of the language over time is what will impact decision making here.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://1148483]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2018-02-22 23:26 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (300 votes). Check out past polls.