=begin pod :kind("Type") :subkind("class") :category("basic")

=TITLE class Sub

=SUBTITLE Subroutine

    class Sub is Routine { }

A type for subroutines and operators. Subs are created with the C<sub>
declarator keyword followed by an optional
L<identifier|/language/syntax#Identifiers>. This
L<short tutorial explains how operators are declared|/language/optut>.
For details of a sub's parameter list, see L<Signature|/type/Signature>.

Note that subs that go by the same name as
L<coercers|/language/typesystem#Coercion> will not take precedence over
them. Use the C<&>-sigil to call them.

    sub Int(Str $s){'what?'};
    say [Int, Int('42'),&Int('42')];
    # OUTPUT: «[(Int) 42 what?]␤»

X<|my (Sub)>X<|our (Sub)>
Subs can be nested and scoped with C<my> and C<our>, whereby C<my> is the
default. A sub declared with C<my> cannot be reached from any outer scope. An
C<our> scoped sub will not redefine a sub of the same name in the outer scope.
Any sub can be accessed via a closure from any outer scope. For instance, in
this example

    sub can-be-seener( $whatever ) {
      my sub can-be-seen ( $objection ) {
        return $whatever but $objection;
      }
      return &can-be-seen
    }

    my $objectioner = can-be-seener( "Really?");
    say $objectioner(42).Int; # OUTPUT: «42␤»

C<$objectioner> will contain the C<can-be-seen> subroutine, even if it has been
declared in another scope; calling it with C<42> will return C<"Really?"> with
the number 42 mixed in, as shown in the last sentence.

=head1 Operators

Operators are also C<Sub>s. Their definition includes
L<the category they belong to|/language/operators#Operator_classification>
and their
L<code, precedence and associativity|/language/functions#Defining_operators>.
The syntax used in their definition is an example of
L<extended identifiers|/language/syntax#Extended_identifiers>.

=head1 Traits
X<|trait_mod (declarator)>

A C<Trait> is a sub that is applied at compile time to various objects like
classes, routines or L<containers|/language/phasers#index-entry-will_trait>. It
is declared with the C<trait_mod> declarator followed by a colon and a string
literal containing the name of the trait. A single positional parameter defines
the type of the object that the trait is applied to. A single named argument
defines the secondary name and may carry arguments when the trait is called.
Traits are a special grammar category and are allowed to be placed after most
language object names or parameter lists.

    say 'start';
    multi sub trait_mod:<is>(Sub $s, :$foo){
        say "⟨is foo⟩ has been called with ⟨$foo⟩ on {$s.WHICH}";
    }
    sub bar() is foo<oi‽> {
        say 'bar has been called'
    }
    bar();
    # OUTPUT: «⟨is foo⟩ has been called with ⟨oi‽⟩ on Sub|47563000␤start␤bar has been called␤»

Use L<destructuring|/type/Signature#Destructuring_Parameters> to call traits
with complex arguments.

    multi trait_mod:<is>(Variable $a, :@foo [$firstpos, *@restpos, :$named, *%restnameds]) {
        say [$firstpos, @restpos, $named, %restnameds]
    }
    my $x is foo[1,2,3,:named<a>, :2b, :3c] = 1
    # OUTPUT: «[1 [2 3] a {b => 2, c => 3}]␤»

Despite its funky syntax, a trait is just a normal C<Sub>. We can apply traits
to it (or even themselves) and we can apply traits to objects at runtime.

    multi sub trait_mod:<is> (Sub $s, :$foo) is foo {
        say 'is foo called'
    }
    sub bar {}
    &trait_mod:<is>(&bar, :foo);
    # OUTPUT: «is foo called␤is foo called␤»

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
