=begin pod

=TITLE class Routine

=SUBTITLE Code object with its own lexical scope and `return` handling

    class Routine is Block { }

A C<Routine> is a code object meant for larger unities of code than L<Block>.
Routine is the common superclass for L<Sub> and L<Method>, the two primary
code objects for code reuse.

Routines serve as a scope limiter for C<return> (i.e. a C<return> returns
from the innermost outer Routine).

Routine is also the level at which multiness (multi subs and multi methods)
are handled.

=head1 Methods

=head2 method name

    method name(Routine:D:) returns Str:D

Returns the name of the sub or method.

=head2 method multi

    method multi(Routine:D:) returns Bool:D

Returns C<True> if the routine is a multi sub or method.

=head2 method candidates

    method candidates(Routine:D:) returns Positional:D

Returns a list of multi candidates, or a one-element list with itself
if it's not a multi

=head2 method wrap

    method wrap(Routine:D: &wrapper)

Wraps (i.e. in-place modifies) the routine. That means a call to this routine
first calls C<&wrapper>, which then can (but doesn't have to) call the
original routine with the C<callsame>, C<callwith>, C<nextsame> and
C<nextwith> dispatchers. The return value from the routine is also
the return value from the wrapper.

C<wrap> returns a wrap handler, which you can pass to L<unwrap> to restore
the original routine.

=head2 method unwrap

    method unwrap(Routine:D: $wraphandler)

Restores the original routine after it has been wrapped with L<wrap>.

=head2 method yada

    method yada(Routine:D:) returns Bool:D

Returns C<True> if the routine is a stub

    say (sub f() { ... }).yada      # True
    say (sub g() { 1;  }).yada      # False

=head2 trait is cached

    multi sub trait_mod:<is>(Routine $r, :$cached!)

Causes the return value of a routine to be stored, so that when subsequent
calls with the same list of arguments are made, the stored value can be
returned immediately instead of re-running the routine.

Useful when storing and returning the computed value is much faster than
re-computing it every time, and when the time saving trumps the cost of the
use of more memory.

Even if the arguments passed to the routine are "reference types" (such as
objects or arrays), then for the purpose of caching they will only be compared
based on their contents. Thus the second invocation will hit the cache in this
case:

    say foo( [1, 2, 3] );   # runs foo
    say foo( [1, 2, 3] );   # doesn't run foo, uses cached value

=begin code
use v6;

sub nth-prime(Int:D $x where * > 0) is cached {
    say "Calculating {$x}th prime";
    return (2..*).grep(*.is-prime)[$x - 1];
}

say nth-prime(43);
say nth-prime(43);
say nth-prime(43);
=end code

produces this output:

=begin code
Calculating 43th prime
191
191
191
=end code

=head2 trait is pure

    multi sub trait_mod:<is>(Routine $r, :!$pure)

Marks a subroutine as I<pure>, that is, it asserts that for the same input, it
will always produce the same output without any additional side effects.

This is a hint to the compiler that it can constant-fold calls to such
functions when the arguments are known at compile time.

    sub double(Numeric:D $x) is pure {
        2 * $x;
    }

=head2 trait is rw

    multi sub trait_mod:<is>(Routine $r, :$rw!)

When a routine is modified with this trait, its return value will be writable.
This is useful when returning variables or writable elements of hashes or
arrays, for example:

=begin code
sub walk(\thing, *@keys) is rw {
    my $current := thing;
    for @keys -> $k {
        if $k ~~ Int {
            $current := $current[$k];
        }
        else {
            $current := $current{$k};
        }
    }
    $current;
}

my %hash;
walk(%hash, 'some', 'key', 1, 2) = 'autovivified';

say %hash.perl;
=end code

produces

=begin code
("some" => {"key" => [Any, [Any, Any, "autovivified"]]}).hash
=end code

Note that C<return> marks return values as read only; if you need an early
exit from an C<is rw> routine, you have to use X<C<return-rw>|return-rw> instead.

=head2 trait is export

    multi sub trait_mod:<is>(Routine $r, :$export!)

Marks a routine as exported to the rest of the world

=begin code :allow<B>
module Foo {
    sub double($x) B<is export> {
        2 * $x
    }
}

import Foo;         # makes sub double available
say double 21;      # 42
=end code

From inside another file you'd say C<use Foo;> to load a module and import the
exported functions.

See L</language/modules#Exporting and Selective Importing> for more details.

=head2 trait is DEPRECATED

    multi sub trait_mod:<is>(Routine:D $r, :$DEPRECATED!)

Marks a routine as deprecated, optionally with a message what to use instead.

This code

=begin code
sub f() is DEPRECATED('the literal 42') { 42 }
say f();
=end code

produces this output:

=begin code
42
Saw 1 occurrence of deprecated code.
================================================================================
Sub f (from GLOBAL) seen at:
  deprecated.p6, line 2
Please use the literal 42 instead.
--------------------------------------------------------------------------------
Please contact the author to have these occurrences of deprecated code
adapted, so that this message will disappear!
=end code

=head2 trait is hidden-from-backtrace

    multi sub trait_mod:<is>(Routine:D, :$hidden-from-backtrace!)

Hides a routine from showing up in a default backtrace. For example

=begin code
sub inner { die "OH NOEZ" };
sub outer { inner() };
outer();
=end code

produces the error message and backtrace

=begin code
OH NOEZ
  in sub inner at bt.p6:1
  in sub outer at bt.p6:2
  in block <unit> at bt.p6:3
=end code

but if C<inner> is marked with C<hidden-from-backtrace>

=begin code
sub inner is hidden-from-backtrace { die "OH NOEZ" };
sub outer { inner() };
outer();
=end code

the error backtrace does not show it:

=begin code
OH NOEZ
  in sub outer at bt.p6:2
  in block <unit> at bt.p6:3
=end code

=begin comment

TODO: explain export tags

=end comment

=end pod
