Synopsis 6
by Damian Conway, Allison RandalApril 09, 2003
This document summarizes Apocalypse 6, which covers subroutines and the new type system.
Subroutines and Other Code Objects
Subroutines (keyword: sub) are noninheritable routines with
parameter lists.
Methods (keyword: method) are inheritable routines that always
have an associated object (known as their invocant) and belong to a
particular class.
Submethods (keyword: submethod) are noninheritable methods, or
subroutines masquerading as methods. They have an invocant and belong to
a particular class.
Multimethods (keyword: multi) are routines that do not belong to a
particular class, but which have one or more invocants.
Rules (keyword: rule) are methods (of a grammar) that perform
pattern matching. Their associated block has a special syntax (see
Synopsis 5).
Macros (keyword: macro) are routines whose calls execute as soon
as they are parsed (i.e. at compile-time). Macros may return another
source code string or a parse-tree.
Standard Subroutines
The general syntax for named subroutines is any of:
my RETTYPE sub NAME ( PARAMS ) TRAITS {...}
our RETTYPE sub NAME ( PARAMS ) TRAITS {...}
sub NAME ( PARAMS ) TRAITS {...}
The general syntax for anonymous subroutines is:
sub ( PARAMS ) TRAITS {...}
"Trait" is the new name for a compile-time (is) property.
See Traits and Properties
Perl5ish Subroutine Declarations
You can still declare a sub without parameter list, as in Perl 5:
sub foo {...}
Arguments still come in via the @_ array, but they are constant
aliases to actual arguments:
sub say { print qq{"@_"\n}; } # args appear in @_
sub cap { $_ = uc $_ for @_ } # Error: elements of @_ are constant
If you need to modify the elements of @_, then declare it with the is rw
trait:
sub swap (*@_ is rw) { @_[0,1] = @_[1,0] }
Blocks
Raw blocks are also executable code structures in Perl 6.
Every block defines a subroutine, which may either be executed
immediately or passed in as a Code reference argument to some other
subroutine.
"Pointy subs"
The arrow operator -> is almost a synonym for the anonymous
sub keyword. The parameter list of a pointy sub does not require
parentheses and a pointy sub may not be given traits.
$sq = -> $val { $val**2 }; # Same as: $sq = sub ($val) { $val**2 };
for @list -> $elem { # Same as: for @list, sub ($elem) {
print "$elem\n"; # print "$elem\n";
} # }
Stub Declarations
To predeclare a subroutine without actually defining it, use a "stub block":
sub foo {...}; # Yes, those three dots are part of the actual syntax
The old Perl 5 form:
sub foo;
is a compile-time error in Perl 6 (for reasons explained in Apocalypse 6).
Globally Scoped Subroutines
Subroutines and variables can be declared in the global namespace, and are thereafter visible everywhere in a program.
Global subroutines and variables are normally referred to by prefixing
their identifier with *, but it may be omitted if the reference is
unambiguous:
$*next_id = 0;
sub *saith($text) { print "Yea verily, $text" }
module A {
my $next_id = 2; # hides any global or package $next_id
saith($next_id); # print the lexical $next_id;
saith($*next_id); # print the global $next_id;
}
module B {
saith($next_id); # Unambiguously the global $next_id
}
Lvalue Subroutines
Lvalue subroutines return a "proxy" object that can be assigned to. It's known as a proxy because the object usually represents the purpose or outcome of the subroutine call.
Subroutines are specified as being lvalue using the is rw trait.
An lvalue subroutine may return a variable:
my $lastval;
sub lastval () is rw { return $lastval }
or the result of some nested call to an lvalue subroutine:
sub prevval () is rw { return lastval() }
or a specially tied proxy object, with suitably programmed
FETCH and STORE methods:
sub checklastval ($passwd) is rw {
my $proxy is Proxy(
FETCH => sub ($self) {
return lastval();
},
STORE => sub ($self, $val) {
die unless check($passwd);
lastval() = $val;
},
);
return $proxy;
}
Operator Overloading
Operators are just subroutines with special names.
Unary operators are defined as prefix or postfix:
sub prefix:OPNAME ($operand) {...}
sub postfix:OPNAME ($operand) {...}
Binary operators are defined as infix:
sub infix:OPNAME ($leftop, $rightop) {...}
Bracketing operators are defined as circumfix. The leading and trailing delimiters together are the name of the operator.
sub circumfix:LEFTDELIM...RIGHTDELIM ($contents) {...}
sub circumfix:DELIMITERS ($contents) {...}
If the left and right delimiters aren't separated by "...",
then the DELIMITERS string must have an even number of characters. The first
half is treated as the opening delimiter and the second half as
the closing.
Operator names can be any sequence of Unicode characters. For example:
sub infix:(c) ($text, $owner) { return $text but Copyright($owner) }
method prefix:± (Num $x) returns Num { return +$x | -$x }
multi postfix:! (Int $n) { $n<2 ?? 1 :: $n*($n-1)! }
macro circumfix:<!--...--> ($text) { "" }
my $document = $text (c) $me;
my $tolerance = ±7!;
<!-- This is now a comment -->
Parameters and Arguments
Perl 6 subroutines may be declared with parameter lists.
By default, all parameters are constant aliases to their corresponding
arguments -- the parameter is just another name for the original
argument, but the argument can't be modified through it. To allow
modification, use the is rw trait. To pass-by-copy, use the is
copy trait.
Parameters may be required or optional. They may be passed by position, or by name. Individual parameters may confer a scalar or list context on their corresponding arguments.
Arguments destined for required parameters must come before those bound to optional parameters. Arguments destined for positional parameters must come before those bound to named parameters.
Invocant Parameters
A method invocant is specified as the first parameter in the parameter list, with a colon (rather than a comma) immediately after it:
method get_name ($self:) {...}
method set_name ($me: $newname) {...}
The corresponding argument (the invocant) is evaluated in scalar context and is passed as the left operand of the method call operator:
print $obj.get_name();
$obj.set_name("Sam");
Multimethod invocants are specified at the start of the parameter list, with a colon terminating the list of invocants:
multi handle_event ($window, $event: $mode) {...} # two invocants
Multimethod invocant arguments are passed positionally, though the first invocant can be passed via the method call syntax:
# Multimethod calls...
handle_event($w, $e, $m);
$w.handle_event($e, $m);
Invocants may also be passed using the indirect object syntax, with a colon after them. The colon is just a special form of the comma, and has the same precedence:
# Indirect method call...
set_name $obj: "Sam";
# Indirect multimethod call...
handle_event $w, $e: $m;
Passing too many or too few invocants is a fatal error.
The first invocant is always the topic of the corresponding method or multimethod.

