Search code examples
raku

MAIN() function: how does multi-dispatch work?


Example 1:

#!/usr/bin/env raku
use v6.d;

sub MAIN(Int $int) {
    say 'parameter $int: ', $int.^name;
}

--output:--
$ raku b.raku 10   
parameter $int: IntStr

Example 2:

#!/usr/bin/env raku
use v6.d;

sub MAIN(Str $str) {
    say 'parameter $str: ', $str.^name;
}

--output:--
$ raku b.raku 10   
parameter $str: IntStr

$ raku b.raku hello
parameter $str: Str

$ raku b.raku 10hello
parameter $str: Str

$ raku b.raku 6.5    
parameter $str: RatStr

Example 3:

#!/usr/bin/env raku
use v6.d;

multi sub MAIN(Int $int) {
    say 'parameter $int: ', $int.^name;
}

multi sub MAIN(Str $str,) {
    say 'parameter $str: ', $str.^name;
}

--output:--
raku b.raku 10     
Ambiguous call to 'MAIN(IntStr)'; these signatures all match:
  (Int $int)
  (Str $str)
  in block <unit> at b.raku line 2

Okay, that makes sense to me: an IntStr type matches both an Int type and a Str type. (In erlang/elixir, the first matching function clause would win.)

Next, if I add an optional parameter to the second clause of MAIN(), the ambiguity disappears:

Example 4:

#!/usr/bin/env raku
use v6.d;

multi sub MAIN(Int $int) {
    say 'parameter $int: ', $int.^name;
}

multi sub MAIN(Str $str, Int $x?) {
    say 'parameter $str: ', $str.^name;
}


--output:--
raku b.raku 10
parameter $int: IntSt

In this case, the first clause of MAIN() executes. What is the rule to explain that?


Solution

  • Because the second candidate can have 2 arguments, it is less tight than the first candidate that must have one argument.