I am trying to use multi
in my Raku code that wraps a function in C
.
Here I am calling lchoose
function in shared libray Rmath
.
This is my code which works:
use NativeCall;
constant RMATH = "./Rmath"; # shared library
sub lchoose(num64, num64) returns num64
is native( RMATH ) { * };
# The C function signature is
# double lchoose(double, double);
sub r_lchoose($n,$r) {
return lchoose($n.Num, $r.Num)
}
say r_lchoose(9,8) # 2.1972245773362196
But this does not work. The code keeps on running/hanging. Neither dies nor throws any output:
use NativeCall;
constant RMATH = "./Rmath"; # shared library
multi lchoose(num64, num64) returns num64
is native( RMATH ) { * };
multi lchoose($n,$r) {
lchoose($n.Num, $r.Num)
}
say lchoose(9,8) # Neither dies nor throws any output
My expectation is when I call lchoose(9,8)
it should call second multi as the arguments are definitely not num64
. If it had used second function, then it would have called the first function and given the output.
Or atleast I expected the program to throw error rather than hang.
OS information
Windows 11 64-bit
Raku information
Welcome to Rakudo™ v2022.04.0000.1.
Implementing the Raku® Programming Language v6.d.
Built on MoarVM version 2022.04-3-ga9fcd5a74.
A
num64
in a signature indicate that it MUST have anum64
for a multi dispatch to work. Otherwise you could not set up candidates for aNum:D
and have a candidate fornum64
ornum32
.And because there is no candidate for
Num
in your example, it will dispatch back to the original candidate, causing the infiniloop.I would therefore write the "catch-all" lchoose candidate as:
In the signature we convert everything to
Num
, and then we assign these to nameless nativenum64
variables in the call the other candidate (which will now dispatch correctly).