txt: ## multi.md
  multi
  
  Combined from primary sources listed below.
  
  # [In Functions](#___top "go to top of document")[§](#(Functions)_multi_multi "direct link")
  
  See primary documentation
  [in context](/language/functions#Multi-dispatch)
  for **Multi-dispatch**.
  
  Raku allows for writing several routines with the same name but different signatures. When the routine is called by name, the runtime environment determines the proper *candidate* and invokes it.
  
  Each candidate is declared with the `multi` keyword. Dispatch happens depending on the parameter [arity](/type/Code#method_arity) (number), type and name; and under some circumstances the order of the multi declarations. Consider the following example:
  
  ```raku
  # version 1
  multi happy-birthday( $name ) {
      say "Happy Birthday $name !";
  }
  
  # version 2
  multi happy-birthday( $name, $age ) {
      say "Happy {$age}th Birthday $name !";
  }
  
  # version 3
  multi happy-birthday( :$name, :$age, :$title  = 'Mr' ) {
      say "Happy {$age}th Birthday $title $name !";
  }
  
  
  # calls version 1 (arity)
  happy-birthday 'Larry';                        # OUTPUT: «Happy Birthday Larry !␤»
  # calls version 2 (arity)
  happy-birthday 'Luca', 40;                     # OUTPUT: «Happy 40th Birthday Luca !␤»
  # calls version 3
  # (named arguments win against arity)
  happy-birthday( age => '50', name => 'John' ); # OUTPUT: «Happy 50th Birthday Mr John !␤»
  # calls version 2 (arity)
  happy-birthday( 'Jack', 25 );                  # OUTPUT: «Happy 25th Birthday Jack !␤»
  
  ```
  
  The first two versions of the `happy-birthday` sub differs only in the arity (number of arguments), while the third version uses named arguments and is chosen only when named arguments are used, even if the arity is the same of another `multi` candidate.
  
  When two sub have the same arity, the type of the arguments drive the dispatch; when there are named arguments they drive the dispatch even when their type is the same as another candidate:
  
  ```raku
  multi happy-birthday( Str $name, Int $age ) {
      say "Happy {$age}th Birthday $name !";
  }
  
  multi happy-birthday( Str $name, Str $title ) {
      say "Happy Birthday $title $name !";
  }
  
  multi happy-birthday( Str :$name, Int :$age ) {
      say "Happy Birthday $name, you turned $age !";
  }
  
  happy-birthday 'Luca', 40;                 # OUTPUT: «Happy 40th Birthday Luca !␤»
  happy-birthday 'Luca', 'Mr';               # OUTPUT: «Happy Birthday Mr Luca !␤»
  happy-birthday age => 40, name => 'Luca';  # OUTPUT: «Happy Birthday Luca, you turned 40 !␤»
  
  ```
  
  Named parameters participate in the dispatch even if they are not provided in the call. Therefore a multi candidate with named parameters will be given precedence.
  
  For more information about type constraints see the documentation on [`Signature` literals](/language/signatures#Type_constraints).
  
  ```raku
  multi as-json(Bool $d) { $d ?? 'true' !! 'false'; }
  multi as-json(Real $d) { ~$d }
  multi as-json(@d)      { sprintf '[%s]', @d.map(&as-json).join(', ') }
  
  say as-json( True );                        # OUTPUT: «true␤»
  say as-json( 10.3 );                        # OUTPUT: «10.3␤»
  say as-json( [ True, 10.3, False, 24 ] );   # OUTPUT: «[true, 10.3, false, 24]␤»
  ```
  
  For some signature differences (notably when using a where clause or a subset) the order of definition of the multi methods or subs is used, evaluating each possibility in turn. See [multi resolution by order of definition](/language/functions#multi_resolution_by_order_of_definition) below for examples.
  
  `multi` without any specific routine type always defaults to a `sub`, but you can use it on methods as well. The candidates are all the multi methods of the object:
  
  ```raku
  class Congrats {
      multi method congratulate($reason, $name) {
          say "Hooray for your $reason, $name";
      }
  }
  
  role BirthdayCongrats {
      multi method congratulate('birthday', $name) {
          say "Happy birthday, $name";
      }
      multi method congratulate('birthday', $name, $age) {
          say "Happy {$age}th birthday, $name";
      }
  }
  
  my $congrats = Congrats.new does BirthdayCongrats;
  
  $congrats.congratulate('promotion','Cindy'); # OUTPUT: «Hooray for your promotion, Cindy␤»
  $congrats.congratulate('birthday','Bob');    # OUTPUT: «Happy birthday, Bob␤»
  ```
  
  Unlike `sub`, if you use named parameters with multi methods, the parameters must be required parameters to behave as expected.
  
  Please note that a non-multi sub or operator will hide multi candidates of the same name in any parent scope or child scope. The same is true for imported non-multi candidates.
  
  Multi-dispatch can also work on parameter traits, with routines with `is rw` parameters having a higher priority than those that do not:
  
  ```raku
  proto þoo (|) {*}
  multi þoo( $ðar is rw ) { $ðar = 42 }
  multi þoo( $ðar ) { $ðar + 42 }
  my $bar = 7;
  say þoo($bar); # OUTPUT: «42␤»
  
  ```
  