`nqp::isnum` returns 0 for everything Rakudo considers a `Num`
ab5tract opened this issue · comments
nqp::isnum
appears to be pretty broken, at least from the use case of an (ahem, the) HLL:
> r 'use nqp; my Num $f = 11.1e0; dd :istype(nqp::istype($f, Num)), :isnum(nqp::isnum($f))'
:isnum(0)
:istype(1)
> r 'use nqp; my num $f = 11.1e0; dd :istype(nqp::istype($f, Num)), :isnum(nqp::isnum($f))'
:isnum(0)
:istype(1)
> r 'use nqp; my num32 $f = 11.1e0; dd :istype(nqp::istype($f, Num)), :isnum(nqp::isnum($f))'
:isnum(0)
:istype(1)
> r 'use nqp; my num64 $f = 11.1e0; dd :istype(nqp::istype($f, Num)), :isnum(nqp::isnum($f))'
:isnum(0)
:istype(1)
Num
s aren't num
s, so perhaps it makes sense that nqp::isnum
returns 0
for Num
s:
use nqp;
say nqp::isnum(Num); # 0
say nqp::isnum(num); # 1
That said:
multi qux (Num) { 'Num' }
multi qux (num) { 'num' }
my num $foo = 42e0;
say qux $foo; # num
say $foo.WHAT; # (Num)
say $foo.VAR.WHAT; # (NumLexRef)
my num \bar = $foo; # Type check failed in binding; expected num but got Num (42e0)
@raiph Other nqp
operations that are documented as expecting num
arguments happily accept the whole Num
tower.
This is not sensible useful behavior in my opinion:
> r 'use nqp; dd :isnum(nqp::isnum(my num $n = 5e0))'
:isnum(0)
> r 'use nqp; dd :isnum(nqp::isnum(num))'
:isnum(1)
Whereas nqp::isnanorinf
acts like this:
> r 'use nqp; dd :isinf(nqp::isnanorinf(my num $n = Inf))'
:isinf(1)
> r 'use nqp; dd :isinf(nqp::isnanorinf(my num64 $n = Inf))'
:isinf(1)
> r 'use nqp; dd :isinf(nqp::isnanorinf(my Num $n = Inf))'
:isinf(1)
You raise an interesting dynamic, but that is a bit beyond the scope of this issue IMO.
This is working as intended. The is* nqp ops are all very strict and do REPR checks. NQP is our low level language and these ops by design don't do any magic to just DWIM. They are for when you really need to know whether something is a low level type (int, str, num). Other nqp ops are more forgiving because they may auto-unbox. Num for example has a num $!value
attribute that is a box target, so unboxing will just return this contained low level num.