txt: ## signatures.md
  ## Chunk 1 of 2
  Signature literals
  
  A guide to signatures in Raku
  
  [`Signatures`](/type/Signature) appear inside parentheses after [subroutine](/type/Sub) and [method](/type/Method) names, on blocks after a `->` or `<->` arrow, as the input to [variable declarators](/language/variables#Variable_declarators_and_scope) like [`my`](/syntax/my), or as a separate term starting with a colon.
  
  ```raku
  sub f($x) { }
  #    ^^^^ Signature of sub f
  my method x() { }
  #          ^^ Signature of a method
  my $s = sub (*@a) { }
  #           ^^^^^ Signature of an anonymous function
  
  for <a b c> -> $x { }
  #              ^^   Signature of a Block
  
  my ($a, @b) = 5, (6, 7, 8);
  #  ^^^^^^^^ Signature of a variable declarator
  
  my $sig = :($a, $b);
  #          ^^^^^^^^ Standalone Signature object
  ```
  
  Signature literals can be used to define the signature of a callback or a closure.
  
  ```raku
  sub f(&c:(Int)) { }
  sub will-work(Int) { }
  sub won't-work(Str) { }
  f(&will-work);
  
  f(&won't-work);
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::TypeCheck::Binding::Parameter: Constraint type check failed in binding to parameter '&c'␤»
  
  f(-> Int { 'this works too' } );
  ```
  
  You can use any kind of literal, including numeric ones, as part of a signature; this is generally used in conjunction with multis
  
  ```raku
  proto stuff(|) {*}
  multi stuff(33) { 58 }
  multi stuff(⅓) { 43 }
  multi stuff(Int)  { 3 }
  multi stuff(Complex)  { 66 }
  say stuff($_) for (33, ⅓, i, 48); # OUTPUT: «58␤43␤66␤3␤»
  
  ```
  
  However, you can't use `True` or `False` as literals in signatures since they will always succeed (or fail). A warning will be issued if you do so:
  
  ```raku
  sub foo(True) {};
  my $sig =  :( True );
  
  ```
  
  They will both warn "Literal values in signatures are smartmatched against and smartmatch with `True` will always succeed. Use the `where` clause instead.". Use of `False` will produce a similar warning.
  
  Smartmatching signatures against a [`List`](/type/List) is supported.
  
  ```raku
  my $sig = :(Int $i, Str $s);
  say (10, 'answer') ~~ $sig;
  # OUTPUT: «True␤»
  my $sub = sub ( Str $s, Int $i ) { return $s xx $i };
  say $sub.signature ~~ :( Str, Int );
  # OUTPUT: «True␤»
  given $sig {
      when :(Str, Int) { say 'mismatch' }
      when :($, $)     { say 'match' }
      default          { say 'no match' }
  }
  # OUTPUT: «match␤»
  ```
  
  It matches the second `when` clause since `:($, $)` represents a [`Signature`](/type/Signature) with two scalar, anonymous, arguments, which is a more general version of `$sig`.
  
  When smartmatching against a [`Hash`](/type/Hash), the signature is assumed to consist of the keys of the [`Hash`](/type/Hash).
  
  ```raku
  my %h = left => 1, right => 2;
  say %h ~~ :(:$left, :$right);
  # OUTPUT: «True␤»
  ```
  
  [`Signature`](/type/Signature) literals can contain string/numeric literals
  
  ```raku
  my $sig = :('Þor', Str, Int);
  say <Þor Hammer 1> ~~ $sig; # OUTPUT: «True␤»
  ```
  
  And they can also contain the invocant marker
  
  ```raku
  class Foo {
      method bar( $self: ){ "baz" }
  };
  say Foo.^methods.first(*.name eq 'bar').signature ~~ :($: *%) ;
  # OUTPUT: «True␤»
  ```
  
  # [Parameter separators](#Signature_literals "go to top of document")[§](#Parameter_separators "direct link")
  
  A signature consists of zero or more [`Parameter`](/type/Parameter)s, separated by commas.
  
  ```raku
  my $sig = :($a, @b, %c);
  sub add($a, $b) { $a + $b };
  ```
  
  As an exception the first parameter may be followed by a colon instead of a comma to mark the invocant of a method. This is done in order to distinguish it from what would then be a regular positional parameter. The invocant is the object that was used to call the method, which is usually bound to [`self`](/routine/self). By specifying it in the signature, you can change the variable name it is bound to.
  
  ```raku
  method ($a: @b, %c) {};       # first argument is the invocant
  
  class Foo {
      method whoami($me:) {
          "Well I'm class $me.^name(), of course!"
      }
  }
  say Foo.whoami; # OUTPUT: «Well I'm class Foo, of course!␤»
  ```
  
  # [Type constraints](#Signature_literals "go to top of document")[§](#Type_constraints "direct link")
  
  Parameters can optionally have a type constraint (the default is [`Any`](/type/Any)). These can be used to restrict the allowed input to a function.
  
  ```raku
  my $sig = :(Int $a, Str $b);
  
  ```
  
  Type constraints can have any compile-time defined value
  
  ```raku
  subset Positive-integer of Int where * > 0;
  sub divisors(Positive-integer $n) { $_ if $n %% $_ for 1..$n };
  CATCH { default { put .^name, ': ', .Str; .resume } };
  
  divisors 2.5;
  # OUTPUT: «X::TypeCheck::Binding::Parameter: Type check failed in binding to parameter '$n'; expected Positive-integer but got Rat (2.5)␤»
  
  divisors -3;
  # OUTPUT: «X::TypeCheck::Binding::Parameter: Constraint type check failed in binding to parameter '$n'; expected Positive-integer but got Int (-3)␤»
  
  ```
  
  Please note that in the code above type constraints are enforced at two different levels: the first level checks if it belongs to the type in which the subset is based, in this case [`Int`](/type/Int). If it fails, a `Type check` error is produced. Once that filter is cleared, the constraint that defined the subset is checked, producing a `Constraint type check` error if it fails.
  
  Type constraints can define multiple allowable types
  
  ```raku
  sub abbrev($arg where Str|List|Hash) {...} # throws if $arg is not one of those types
  
  ```
  
  Anonymous arguments are fine too, if you don't actually need to refer to a parameter by name, for instance to distinguish between different signatures in a [multi](/language/functions#Multi-dispatch) or to check the signature of a [`Callable`](/type/Callable).
  
  ```raku
  my $sig = :($, @, %a);          # two anonymous and a "normal" parameter
  $sig = :(Int, Positional);      # just a type is also fine (two parameters)
  sub baz(Str) { "Got passed a Str" }
  
  ```
  
  Type constraints may also be [type captures](/language/signatures#Type_captures).
  
  In addition to those *nominal* types, additional constraints can be placed on parameters in the form of code blocks which must return a true value to pass the type check
  
  ```raku
  sub f(Real $x where { $x > 0 }, Real $y where { $y >= $x }) { }
  ```
  
  The code in `where` clauses has some limitations: anything that produces side-effects (e.g., printing output, pulling from an iterator, or increasing a state variable) is not supported and may produce surprising results if used. Also, the code of the `where` clause may run more than once for a single typecheck in some implementations.
  
  The `where` clause doesn't need to be a code block, anything on the right of the `where`-clause will be used to [smartmatch](/language/operators#infix_~~) the argument against it. So you can also write:
  
  ```raku
  multi factorial(Int $ where 0) { 1 }
  multi factorial(Int $x)        { $x * factorial($x - 1) }
  ```
  
  The first of those can be shortened to
  
  ```raku
  multi factorial(0) { 1 }
  ```
  
  i.e., you can use a literal directly as a type and value constraint on an anonymous parameter.
  
  **Tip:** pay attention to not accidentally leave off a block when you, say, have several conditions:
  
  ```raku
  -> $y where   .so && .name    {}( sub one   {} ); # WRONG!!
  -> $y where { .so && .name }  {}( sub two   {} ); # OK!
  -> $y where   .so &  .name.so {}( sub three {} ); # Also good
  ```
  
  The first version is wrong and will issue a warning about a sub object coerced to string. The reason is the expression is equivalent to `($y ~~ ($y.so && $y.name))`; that is "call `.so`, and if that is `True`, call `.name`; if that is also `True` use its value for smartmatching…". It's the **result** of `(.so && .name)` it will be smartmatched against, but we want to check that both `.so` and `.name` are truthy values. That is why an explicit Block or a [`Junction`](/type/Junction) is the right version.
  
  All previous arguments that are not part of a sub-signature in a [`Signature`](/type/Signature) are accessible in a `where`-clause that follows an argument. Therefore, the `where`-clause of the last argument has access to all arguments of a signature that are not part of a sub-signature. For a sub-signature place the `where`-clause inside the sub-signature.
  
  ```raku
  sub foo($a, $b where * == $a ** 2) { say "$b is a square of $a" }
  foo 2, 4; # OUTPUT: «4 is a square of 2␤»»
  # foo 2, 3;
  # OUTPUT: «Constraint type check failed in binding to parameter '$b'…»
  ```
  
  ## [Constraining optional arguments](#Signature_literals "go to top of document")[§](#Constraining_optional_arguments "direct link")
  
  [Optional arguments](#Optional_and_mandatory_arguments) can have constraints, too. Any `where` clause on any parameter will be executed, even if it's optional and not provided by the caller. In that case you may have to guard against undefined values within the `where` clause.
  
  ```raku
  sub f(Int $a, UInt $i? where { !$i.defined or $i > 5 }) { ... }
  ```
  
  ## [Constraining slurpy arguments](#Signature_literals "go to top of document")[§](#Constraining_slurpy_arguments "direct link")
  
  [Slurpy arguments](#Slurpy_parameters) can not have type constraints. A `where`-clause in conjunction with a [`Junction`](/type/Junction) can be used to that effect.
  
  ```raku
  sub f(*@a where {$_.all ~~ Int}) { say @a };
  f(42);
  f(<a>);
  CATCH { default { say .^name, ' ==> ', .Str }  }
  # OUTPUT: «[42]␤Constraint type check failed in binding to parameter '@a' ...»
  
  ```
  
  ## [Constraining named arguments](#Signature_literals "go to top of document")[§](#Constraining_named_arguments "direct link")
  
  Constraints against [named arguments](#Positional_vs._named_arguments) apply to the value part of the [colon-pair](/type/Pair).
  
  ```raku
  sub f(Int :$i){};
  f :i<forty-two>;
  CATCH { default { say .^name, ' ==> ', .Str }  }
  # OUTPUT: «X::TypeCheck::Binding::Parameter ==> Type check failed in
  # binding to parameter '$i'; expected Int but got Str ("forty-two")␤»
  ```
  
  ## [Constraining argument definiteness](#Signature_literals "go to top of document")[§](#Constraining_argument_definiteness "direct link")
  
  Normally, a type constraint only checks whether the value of the parameter is of the correct type. Crucially, both *object instances* and *type objects* will satisfy such a constraint as illustrated below:
  
  ```raku
  say  42.^name;    # OUTPUT: «Int␤»
  say  42 ~~ Int;   # OUTPUT: «True␤»
  say Int ~~ Int;   # OUTPUT: «True␤»
  ```
  
  Note how both `42` and [`Int`](/type/Int) satisfy the match.
  
  Sometimes we need to distinguish between these object instances (`42`) and type objects ([`Int`](/type/Int)). Consider the following code:
  
  ```raku
  sub limit-lines(Str $s, Int $limit) {
      my @lines = $s.lines;
      @lines[0 .. min @lines.elems, $limit].join("\n")
  }
  say (limit-lines "a \n b \n c \n d \n", 3).raku; # "a \n b \n c \n d "
  say limit-lines Str, 3;
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::Multi::NoMatch: Cannot resolve caller lines(Str: );
  # none of these signatures match:
  #     (Str:D $: :$count!, *%_)
  #     (Str:D $: $limit, *%_)
  #     (Str:D $: *%_)»
  say limit-lines "a \n b", Int; # Always returns the max number of lines
  ```
  
  Here we really only want to deal with string instances, not type objects. To do this, we can use the `:D` type constraint. This constraint checks that the value passed is an *object instance*, in a similar fashion to calling its [DEFINITE](/language/mop#DEFINITE) (meta)method.
  
  To warm up, let's apply `:D` to the right-hand side of our humble [`Int`](/type/Int) example:
  
  ```raku
  say  42 ~~ Int:D;  # OUTPUT: «True␤»
  say Int ~~ Int:D;  # OUTPUT: «False␤»
  ```
  
  Note how only `42` matches `Int:D` in the above.
  
  Returning to `limit-lines`, we can now amend its signature to catch the error early:
  
  ```raku
  sub limit-lines(Str:D $s, Int $limit) { };
  say limit-lines Str, 3;
  CATCH { default { put .^name ~ '--' ~ .Str } };
  # OUTPUT: «Parameter '$s' of routine 'limit-lines' must be an object instance of type 'Str',
  #          not a type object of type 'Str'.  Did you forget a '.new'?»
  ```
  
  This is much better than the way the program failed before, since here the reason for failure is clearer.
  
  It's also possible that *type objects* are the only ones that make sense for a routine to accept. This can be done with the `:U` type constraint, which checks whether the value passed is a type object rather than an object instance. Here's our [`Int`](/type/Int) example again, this time with `:U` applied:
  
  ```raku
  say  42 ~~ Int:U;  # OUTPUT: «False␤»
  say Int ~~ Int:U;  # OUTPUT: «True␤»
  ```
  
  Now `42` fails to match `Int:U` while [`Int`](/type/Int) succeeds.
  
  Here's a more practical example:
  
  ```raku
  sub can-turn-into(Str $string, Any:U $type) {
     return so $string.$type;
  }
  say can-turn-into("3", Int);        # OUTPUT: «True␤»
  say can-turn-into("6.5", Int);      # OUTPUT: «True␤»
  say can-turn-into("6.5", Num);      # OUTPUT: «True␤»
  say can-turn-into("a string", Num); # OUTPUT: «False␤»
  ```
  
  Calling `can-turn-into` with an object instance as its second parameter will yield a constraint violation as intended:
  
  ```raku
  say can-turn-into("a string", 123);
  # OUTPUT: «Parameter '$type' of routine 'can-turn-into' must be a type object
  # of type 'Any', not an object instance of type 'Int'...»
  
  ```
  
  For explicitly indicating the normal behavior, that is, not constraining whether the argument will be an instance or a type object, `:_` can be used but this is unnecessary since this is the default constraint (of this kind) on arguments. Thus, `:(Num:_ $)` is the same as `:(Num $)`.
  
  To recap, here is a quick illustration of these type constraints, also known collectively as *type smileys*:
  
  ```raku
  # Checking a type object
  say Int ~~ Any:D;    # OUTPUT: «False␤»
  say Int ~~ Any:U;    # OUTPUT: «True␤»
  say Int ~~ Any:_;    # OUTPUT: «True␤»
  
  # Checking a subset
  subset Even of Int where * // 2;
  say 3 ~~ Even:D;     # OUTPUT: «True␤»
  say 3 ~~ Even:U;     # OUTPUT: «False␤»
  say Int ~~ Even:U;   # OUTPUT: «True␤»
  
  # Checking an object instance
  say 42 ~~ Any:D;     # OUTPUT: «True␤»
  say 42 ~~ Any:U;     # OUTPUT: «False␤»
  say 42 ~~ Any:_;     # OUTPUT: «True␤»
  
  # Checking a user-supplied class
  class Foo {};
  say Foo ~~ Any:D;    # OUTPUT: «False␤»
  say Foo ~~ Any:U;    # OUTPUT: «True␤»
  say Foo ~~ Any:_;    # OUTPUT: «True␤»
  
  # Checking an instance of a class
  my $f = Foo.new;
  say $f  ~~ Any:D;    # OUTPUT: «True␤»
  say $f  ~~ Any:U;    # OUTPUT: «False␤»
  say $f  ~~ Any:_;    # OUTPUT: «True␤»
  ```
  
  The [Classes and Objects](/language/classtut) document further elaborates on the concepts of instances and type objects and discovering them with the `.DEFINITE` method.
  
  Keep in mind all parameters have values; even optional ones have default values that are the type object of the constrained type for explicit type constraints. If no explicit type constraint exists, the default value is an [`Any`](/type/Any) type object for methods, submethods, and subroutines, and a [`Mu`](/type/Mu) type object for blocks. This means that if you use the `:D` type smiley, you'd need to provide a default value or make the parameter required. Otherwise, the default value would be a type object, which would fail the definiteness constraint.
  
  ```raku
  sub divide (Int:D :$a = 2, Int:D :$b!) { say $a/$b }
  divide :1a, :2b; # OUTPUT: «0.5␤»
  ```
  
  The default value will kick in when that particular parameter, either positional or named, gets no value *at all*.
  
  ```raku
  sub f($a = 42){
    my $b is default('answer');
    say $a;
    $b = $a;
    say $b
  };
  f;     # OUTPUT: «42␤42␤»
  f Nil; # OUTPUT: «Nil␤answer␤»
  ```
  
  `$a` has 42 as its default value. With no value, `$a` will be assigned the default value declared in the [`Signature`](/type/Signature). However, in the second case, it *does* receive a value, which happens to be [`Nil`](/type/Nil). Assigning [`Nil`](/type/Nil) to any variable resets it to its default value, which has been declared as `'answer'` by use of the *default* trait. That explains what happens the second time we call `f`. Routine parameters and variables deal differently with default value, which is in part clarified by the different way default values are declared in each case (using `=` for parameters, using the `default` trait for variables).
  
  Note: in 6.c language, the default value of `:U`/`:D` constrained variables was a type object with such a constraint, which is not initializable, thus you cannot use the `.=` operator, for example.
  
  ```raku
  use v6.c;
  my Int:D $x .= new: 42;
  # OUTPUT: You cannot create an instance of this type (Int:D)
  # in block <unit> at -e line 1
  
  ```
  
  In the 6.d language, the default *default* is the type object without the smiley constraint:
  
  ```raku
  use v6.d;
  my Int:D $x .= new: 42; # OUTPUT: «42␤»
  
  ```
  
  A closing remark on terminology: this section is about the use of the type smileys `:D` and `:U` to constrain the definiteness of arguments. Occasionally *definedness* is used as a synonym for *definiteness*; this may be confusing, since the terms have subtly different meanings.
  
  As explained above, *definiteness* is concerned with the distinction between type objects and object instances. A type object is always indefinite, while an object instance is always definite. Whether an object is a type object/indefinite or an object instance/definite can be verified using the [DEFINITE](/language/mop#DEFINITE) (meta)method.
  
  *Definiteness* should be distinguished from *definedness*, which is concerned with the difference between defined and undefined objects. Whether an object is defined or undefined can be verified using the `defined`-method, which is implemented in class [`Mu`](/type/Mu). By default a type object is considered undefined, while an object instance is considered defined; that is: `.defined` returns `False` on a type object, and `True` otherwise. But this default behavior may be overridden by subclasses. An example of a subclass that overrides the default `.defined` behavior is [`Failure`](/type/Failure), so that even an instantiated [`Failure`](/type/Failure) acts as an undefined value:
  
  ```raku
  my $a = Failure;                # Initialize with type object
  my $b = Failure.new("foo");     # Initialize with object instance
  say $a.DEFINITE;                # OUTPUT: «False␤» : indefinite type object
  say $b.DEFINITE;                # OUTPUT: «True␤»  : definite object instance
  say $a.defined;                 # OUTPUT: «False␤» : default response
  say $b.defined;                 # OUTPUT: «False␤» : .defined override
  ```
  
  ## [Constraining signatures of](#Signature_literals "go to top of document") [`Callable`](/type/Callable)s[§](#Constraining_signatures_of_Callables "direct link")
  
  :u
  
  whitespace allowed):
  
  ```raku
  sub apply(&l:(Int:D --> Int:D), Int:D \n) {
      l(n)
  }
  
  sub identity(Int:D \i --> Int:D) { i }
  sub double(Int:D \x --> Int:D) { 2 * x }
  
  say apply &identity, 10; # OUTPUT: «10␤»
  say apply &double, 10;   # OUTPUT: «20␤»
  ```
  
  Typed [lambdas](/language/functions#Blocks_and_lambdas) also work with constrained callable parameters.
  
  ```raku
  say apply -> Int:D \x --> Int:D { 2 * x }, 3;  # OUTPUT: «6␤»
  say apply -> Int:D \x --> Int:D { x ** 3 }, 3; # OUTPUT: «27␤»
  
  ```
  
  Note that this shorthand syntax is available only for parameters with the `&` sigil. For others, you need to use the long version:
  
  ```raku
  sub play-with-tens($c where .signature ~~ :(Int, Str)) { say $c(10, 'ten') }
  sub by-joining-them(Int $i, Str $s) { $s ~ $i }
  play-with-tens &by-joining-them;                              # OUTPUT: «ten10␤»
  play-with-tens -> Int \i, Str \s { s x (1..10).roll mod i };  # OUTPUT: «tenten␤»
  
  sub g(Num $i, Str $s) { $s ~ $i }
  # play-with-tens(&g); # Constraint type check failed
  ```
  
  ## [Constraining return types](#Signature_literals "go to top of document")[§](#Constraining_return_types "direct link")
  
  There are multiple ways to constrain return types on a [`Routine`](/type/Routine). All versions below are currently valid and will force a type check on successful execution of a routine.
  
  [`Nil`](/type/Nil) and [`Failure`](/type/Failure) are always allowed as return types, regardless of any type constraint. This allows [`Failure`](/type/Failure) to be returned and passed on down the call chain.
  
  ```raku
  sub foo(--> Int) { Nil };
  say foo.raku; # OUTPUT: «Nil␤»
  ```
  
  Type captures are not supported.
  
  ### [Return type arrow: `--`>](#Signature_literals "go to top of document")[§](#Return_type_arrow:_--> "direct link")
  
  This form of indicating return types (or constants) in the signature is preferred, since it can handle constant values while the others can't. For consistency, it is the only form accepted on this site.
  
  The return type arrow has to be placed at the end of the parameter list, with or without a `,` before it.
  
  ```raku
  sub greeting1(Str $name  --> Str) { say "Hello, $name" } # Valid
  sub greeting2(Str $name, --> Str) { say "Hello, $name" } # Valid
  
  sub favorite-number1(--> 42) {        } # OUTPUT: 42
  sub favorite-number2(--> 42) { return } # OUTPUT: 42
  
  ```
  
  If the type constraint is a constant expression, it is used as the return value of the routine. Any return statement in that routine has to be argumentless.
  
  ```raku
  sub foo(Str $word --> 123) { say $word; return; }
  my $value = foo("hello"); # OUTPUT: hello
  say $value;               # OUTPUT: 123
  
  ```
  
  ```raku
  # The code below will not compile
  sub foo(Str $word --> 123) { say $word; return $word; }
  my $value = foo("hello");
  say $value;
  
  ```
  
  ### [`returns`](#Signature_literals "go to top of document")[§](#returns "direct link")
  
  The keyword `returns` following a signature declaration has the same function as `-->` with the caveat that this form does not work with constant values. You cannot use it in a block either. That is why the pointy arrow form is always preferred.
  
  ```raku
  sub greeting(Str $name) returns Str { say "Hello, $name" } # Valid
  
  ```
  
  ```raku
  sub favorite-number returns 42 {        } # This will fail.
  
  ```
  
  ### [`of`](#Signature_literals "go to top of document")[§](#of "direct link")
  
  `of` is just the real name of the `returns` keyword.
  
  ```raku
  sub foo() of Int { 42 }; # Valid
  
  ```
  
  ```raku
  sub foo() of 42 {  };    # This will fail.
  
  ```
  
  ### [prefix(C-like) form](#Signature_literals "go to top of document")[§](#prefix(C-like)_form "direct link")
  
  This is similar to placing type constraints on variables like `my Type $var = 20;`, except the `$var` is a definition for a routine.
  
  ```raku
  my Int sub bar { 1 };     # Valid
  
  ```
  
  ```raku
  my 42 sub bad-answer {};  # This will fail.
  
  ```
  
  ## [Coercion type](#Signature_literals "go to top of document")[§](#Coercion_type "direct link")
  
  To accept one type but coerce it automatically to another, use the accepted type as an argument to the target type. If the accepted type is [`Any`](/type/Any) it can be omitted.
  
  ```raku
  sub f(Int(Str) $want-int, Str() $want-str) {
      say $want-int.^name ~ ' ' ~ $want-str.^name
  }
  f '10', 10;
  # OUTPUT: «Int Str␤»
  
  sub foo(Date(Str) $d) { say $d.^name; say $d };
  foo "2016-12-01";
  # OUTPUT: «Date␤2016-12-01␤»
  ```
  
  The coercion is performed by calling the method with the name of the type to coerce to, if it exists. In this example, we're calling the builtin method [`Date`](/type/Date) on the [`Str`](/type/Str) class. The method is assumed to return the correct type—no additional checks on the result are currently performed.
  
  Coercion can also be performed on return types:
  
  ```raku
  sub square-str (Int $x --> Str(Int)) {
      $x²
  }
  
  for 2,4, *²  … 256 -> $a {
      say $a, "² is ", square-str( $a ).chars, " figures long";
  }
  
  # OUTPUT: «2² is 1 figures long␤
  #          4² is 2 figures long␤
  #          16² is 3 figures long␤
  #          256² is 5 figures long␤»
  
  ```
  
  In this example, coercing the return type to [`Str`](/type/Str) allows us to directly apply string methods, such as the number of characters.
  
  **Note**: The appropriate method must be available on the argument, so be careful when trying to coerce custom types.
  
  ```raku
  class Foo { }
  
  sub bar(Foo(Int) $x) { say $x }
  
  bar(3);
  # OUTPUT: «Impossible coercion from 'Int' into 'Foo': no acceptable coercion method found␤»
  
  ```
  
  # [Slurpy parameters](#Signature_literals "go to top of document")[§](#Slurpy_parameters "direct link")
  
  A function is variadic if it can take a varying number of arguments; that is, its arity is not fixed. Therefore, [optional](/language/signatures#Optional_and_mandatory_arguments), named, and slurpy parameters make routines that use them *variadic*, and by extension are called variadic arguments. Here we will focus on slurpy parameters, or simply *slurpies*.
  
  An array or hash parameter can be marked as *slurpy* by leading single (\*) or double asterisk (\*\*) or a leading plus (+). A slurpy parameter can bind to an arbitrary number of arguments (zero or more), and it will result in a type that is compatible with the sigil.
  
  These are called "slurpy" because they slurp up any remaining arguments to a function, like someone slurping up noodles.
  
  ```raku
  my $sig1 = :($a, @b);  # exactly two arguments, second must be Positional
  my $sig2 = :($a, *@b); # at least one argument, @b slurps up any beyond that
  my $sig3 = :(*%h);     # no positional arguments, but any number
                         # of named arguments
  
  sub one-arg (@)  { }
  sub slurpy  (*@) { }
  one-arg (5, 6, 7); # ok, same as one-arg((5, 6, 7))
  slurpy  (5, 6, 7); # ok
  slurpy   5, 6, 7 ; # ok
  # one-arg(5, 6, 7) ; # X::TypeCheck::Argument
  # one-arg  5, 6, 7 ; # X::TypeCheck::Argument
  
  sub named-names (*%named-args) { %named-args.keys };
  say named-names :foo(42) :bar<baz>; # OUTPUT: «foo bar␤»
  
  ```
  
  Positional and named slurpies can be combined; named arguments (i.e., [`Pair`](/type/Pair)s) are collected in the specified hash, positional arguments in the array:
  
  ```raku
  sub combined-slurpy (*@a, *%h) { { array => @a, hash => %h } }
  # or: sub combined-slurpy (*%h, *@a) { ... }
  
  say combined-slurpy(one => 1, two => 2);
  # OUTPUT: «{array => [], hash => {one => 1, two => 2}}␤»
  say combined-slurpy(one => 1, two => 2, 3, 4);
  # OUTPUT: «{array => [3 4], hash => {one => 1, two => 2}}␤»
  say combined-slurpy(one => 1, two => 2, 3, 4, five => 5);
  # OUTPUT: «{array => [3 4], hash => {five => 5, one => 1, two => 2}}␤»
  say combined-slurpy(one => 1, two => 2, 3, 4, five => 5, 6);
  # OUTPUT: «{array => [3 4 6], hash => {five => 5, one => 1, two => 2}}␤»
  
  ```
  
  Note that positional parameters aren't allowed after slurpy (or, in fact, after any type of variadic) parameters:
  
  ```raku
  :(*@args, $last);
  # ===SORRY!=== Error while compiling:
  # Cannot put required parameter $last after variadic parameters
  
  ```
  
  Normally a slurpy parameter will create an [`Array`](/type/Array) (or compatible type), create a new [`Scalar`](/type/Scalar) container for each argument, and assign the value from each argument to those [`Scalar`](/type/Scalar)s. If the original argument also had an intermediary [`Scalar`](/type/Scalar) it is bypassed during this process, and is not available inside the called function.
  
  Sigiled parameters will always impose a context on the collected arguments. Sigilless parameters can also be used slurpily, preceded by a + sign, to work with whatever initial type they started with:
  
  ```raku
  sub zipi( +zape ) {
      zape.^name => zape
  };
  say zipi( "Hey "); # OUTPUT: «List => (Hey )␤»
  say zipi( 1...* ); # OUTPUT: «Seq => (...)␤»
  
  ```
  
  Slurpy parameters have special behaviors when combined with some [traits and modifiers](#Parameter_traits_and_modifiers), as described in [the section on slurpy array parameters](/language/signatures#Types_of_slurpy_array_parameters).
  
  Methods automatically get a `*%_` slurpy named parameter added if they don't have another slurpy named parameter declared.
  
  # [Types of slurpy array parameters](#Signature_literals "go to top of document")[§](#Types_of_slurpy_array_parameters "direct link")
  
  There are three variations to slurpy array parameters.
  
  * The single asterisk form flattens passed arguments.
  * The double asterisk form does not flatten arguments.
  * The plus form flattens according to the single argument rule.
  
  Each will be described in detail in the next few sections. As the difference between each is a bit nuanced, examples are provided for each to demonstrate how each slurpy convention varies from the others.
  
  ## [Flattened slurpy](#Signature_literals "go to top of document")[§](#Flattened_slurpy "direct link")
  
  Slurpy parameters declared with one asterisk will flatten arguments by dissolving one or more layers of bare [`Iterable`](/type/Iterable)s.
  
  ```raku
  my @array = <a b c>;
  my $list := <d e f>;
  sub a(*@a)  { @a.raku.say };
  a(@array);                 # OUTPUT: «["a", "b", "c"]␤»
  a(1, $list, [2, 3]);       # OUTPUT: «[1