=encoding utf-8 =head1 NAME Apocalypse_06 - Subroutines =head1 AUTHOR Larry Wall =head1 VERSION Maintainer: Larry Wall Date: 7 Mar 2003 Last Modified: 25 May 2006 Number: 6 Version: 6 This is the Apocalypse on Subroutines. In Perl culture the term "subroutine" conveys the general notion of calling something that returns control automatically when it's done. This "something" that you're calling may go by a more specialized name such as "procedure", "function", "closure", or "method". In Perl 5, all such subroutines were declared using the keyword C regardless of their specialty. For readability, Perl 6 will use alternate keywords to declare special subroutines, but they're still essentially the same thing underneath. Insofar as they all behave similarly, this Apocalypse will have something to say about them. (And if we also leak a few secrets about how method calls work, that will make Apocalypse 12 all the easier--presuming we don't have to un-invent anything between now and then...) Here are the RFCs covered in this Apocalypse. PSA stands for "problem, solution, acceptance", my private rating of how this RFC will fit into Perl 6. I note that none of the RFCs achieved unreserved acceptance this time around. Maybe I'm getting picky in my old age. Or maybe I just can't incorporate anything into Perl without "marking" it... RFC PSA Title --- --- ----- 21 abc Subroutines: Replace C with a generic C function 23 bcc Higher order functions 57 abb Subroutine prototypes and parameters 59 bcr Proposal to utilize C<*> as the prefix to magic subroutines 75 dcr structures and interface definitions 107 adr lvalue subs should receive the rvalue as an argument 118 rrr lvalue subs: parameters, explicit assignment, and wantarray() changes 128 acc Subroutines: Extend subroutine contexts to include name parameters and lazy arguments 132 acr Subroutines should be able to return an lvalue 149 adr Lvalue subroutines: implicit and explicit assignment 154 bdr Simple assignment lvalue subs should be on by default 160 acc Function-call named parameters (with compiler optimizations) 168 abb Built-in functions should be functions 176 bbb subroutine / generic entity documentation 194 acc Standardise Function Pre- and Post-Handling 271 abc Subroutines : Pre- and post- handlers for subroutines 298 cbc Make subroutines' prototypes accessible from Perl 334 abb Perl should allow specially attributed subs to be called as C functions 344 acb Elements of @_ should be read-only by default In Apocalypses 1 through 4, I used the RFCs as a springboard for discussion. In Apocalypse 5 I was forced by the complexity of the redesign to switch strategies and present the RFCs after a discussion of all the issues involved. That was so well received that I'll try to follow the same approach with this and subsequent Apocalypses. But this Apocalypse is not trying to be as radical as the one on regexes. Well, okay, it is, and it isn't. Alright, it I radical, but you'll like it anyway (we hope). At least the old way of calling subroutines still works. Unlike regexes, Perl subroutines don't have a lot of historical cruft to get rid of. In fact, the basic problem with Perl 5's subroutines is that they're not crufty enough, so the cruft leaks out into user-defined code instead, by the Conservation of Cruft Principle. Perl 6 will let you migrate the cruft out of the user-defined code and back into the declarations where it belongs. Then you will think it to be very beautiful cruft indeed (we hope). Perl 5's subroutines have a number of issues that need to be dealt with. First of all, they're just awfully slow, for various reasons: =over 4 =item * Construction of the C<@_> array =item * Needless prepping of potential lvalues =item * General model that forces lots of run-time processing =item * Difficulty of optimization =item * Storage of unneeded context =item * Lack of tail recursion optimization =item * Named params that aren't really =item * Object model that forces double dispatch in some cases =back Quite apart from performance, however, there are a number of problems with usability: =over 4 =item * Not easy to detect type errors at compile time =item * Not possible to specify the signatures of certain built-in functions =item * Not possible to define control structures as subroutines =item * Not possible to type-check any variadic args other than as a list =item * Not possible to have a variadic list providing scalar context to its elements =item * Not possible to have lazy parameters =item * Not possible to define immediate subroutines (macros) =item * Not possible to define subroutines with special syntax =item * Not enough contextual information available at run time. =item * Not enough contextual information available at compile time. =back In general, the consensus is that Perl 5's simple subroutine syntax is just a little I simple. Well, okay, it's a I too simple. While it's extremely orthogonal to always pass all arguments as a single variadic array, that mechanism does not always map well onto the problem space. So in Perl 6, subroutine syntax has blossomed in several directions. But the most important thing to note is that we haven't actually added a lot of syntax. We've added some, but most of new capabilities come in through the generalized trait/property system, and the new type system. But in those cases where specialized syntax buys us clarity, we have not hesitated to add it. (Er, actually, we hesitated quite a lot. Months, in fact.) One obvious difference is that the C on closures is now optional, since every brace-delimited block is now essentially a closure. You can still put the C if you like. But it is only required if the block would otherwise be construed as a hash value; that is, if it appears to contain a list of pairs. You can force any block to be considered a subroutine with the C keyword; likewise you can force any block to be considered a hash value with the C keyword. But in general Perl just dwims based on whether the top-level is a list that happens to have a first argument that is a pair or hash: Block Meaning ----- ------- { 1 => 2 } hash { 1 => 2 } { 1 => 2, 3 => 4 } hash { 1 => 2, 3 => 4 } { 1 => 2, 3, 4 } hash { 1 => 2, 3 => 4 } { %foo, 1 => 2 } hash { %foo.pairs, 1 => 2 } [Update: C has been demoted to a list operator, actually.] Anything else that is not a list, or does not start with a pair or hash, indicates a subroutine: { 1 } sub { return 1 } { 1, 2 } sub { return 1, 2 } { 1, 2, 3 } sub { return 1, 2, 3 } { 1, 2, 3 => 4 } sub { return 1, 2, 3 => 4 } { pair 1,2,3,4 } sub { return 1 => 2, 3 => 4 } { gethash() } sub { return gethash() } This is a syntactic distinction, not a semantic one. That last two examples are taken to be subs despite containing functions returning pairs or hashes. Note that it would save no typing to recognize the C method specially, since C automatically does pairing of non-pairs. So we distinguish these: { pair 1,2,3,4 } sub { return 1 => 2, 3 => 4 } hash { 1,2,3,4 } hash { 1 => 2, 3 => 4 } If you're worried about the compiler making bad choices before deciding whether it's a subroutine or hash, you shouldn't. The two constructs really aren't all that far apart. The C keyword could in fact be considered a function that takes as its first argument a closure returning a hash value list. So the compiler might just compile the block as a closure in either case, then do the obvious optimization. Although we say the C keyword is now optional on a closure, the C keyword only works with an explicit C. (There are other ways to return values from a block.) [Update: This is slightly inaccurate; C works from any C. See below.] =head2 Subroutine Declarations You may still declare a sub just as you did in Perl 5, in which case it behaves much like it did in Perl 5. To wit, the arguments still come in via the C<@_> array. When you say: sub foo { print @_ } that is just syntactic sugar for this: sub foo (*@_) { print @_ } That is, Perl 6 will supply a default parameter signature (the precise meaning of which will be explained below) that makes the subroutine behave much as a Perl 5 programmer would expect, with all the arguments in C<@_>. It is not exactly the same, however. You may not modify the arguments via C<@_> without declaring explicitly that you want to do so. So in the rare cases that you want to do that, you'll have to supply the C trait (meaning the arguments should be considered "read-write"): sub swap (*@_ is rw) { @_[0,1] = @_[1,0] }; The Perl5-to-Perl6 translator will try to catch those cases and add the parameter signature for you when you want to modify the arguments. (Note: we will try to be consistent about using "arguments" to mean the actual values you pass to the function when you call it, and "parameters" to mean the list of lexical variables declared as part of the subroutine signature, through which you access the values that were passed to the subroutine.) Perl 5 has rudimentary prototypes, but Perl 6 type signatures can be much more expressive if you want them to be. The entire declaration is much more flexible. Not only can you declare types and names of individual parameters, you can add various traits to the parameters, such as C above. You can add traits to the subroutine itself, and declare the return type. In fact, at some level or other, the subroutine's signature and return type are also just traits. You might even consider the body of the subroutine to be a trait. For those of you who have been following Perl 6 development, you'll wonder why we're now calling these "traits" rather than "properties". They're all really still properties under the hood, but we're trying to distinguish those properties that are expected to be set on containers at compile time from those that are expected to be set on values at run time. So compile-time properties are now called "traits". Basically, if you declare it with C, it's a trait, and if you add it onto a value with C, it's a property. The main reason for making the distinction is to keep the concepts straight in people's minds, but it also has the nice benefit of telling the optimizer which properties are subject to change, and which ones aren't. A given trait may or may not be implemented as a method on the underlying container object. You're not supposed to care. [Update: Actually, they're done as mixins if the container type doesn't already support the role. See A12.] There are actually several syntactic forms of trait: rule trait :w { is [\( \)]? | will | of | returns } [Update: the C<:w> is no longer needed on a rule.] (We're specifying the syntax here using Perl 6 regexes. If you don't know about those, go back and read Apocalypse 5.) A C<< >> is actually allowed to be a junction of types: sub foo returns Int|Str {...} The C syntax specifically introduces a closure trait without requiring the extra parens that C would. Saying: will flapdoodle { flap() and doodle() } is exactly equivalent to: is flapdoodle({ flap() and doodle() }) but reads a little better. More typically you'll see traits like: will first { setup() } will last { teardown() } The final block of a subroutine declaration is the "do" trait. Saying: sub foo { ... } is like saying: sub foo will do { ... } Note however that the closure eventually stored under the C trait may in fact be modified in various ways to reflect argument processing, exception handling, and such. We'll discuss the C and C traits later when we discuss types. Back to syntax. =head3 The C form A subroutine can be declared as lexically scoped, package scoped, or unscoped: rule lexicalsub :w { ? ? * } rule packagesub :w { ? * } rule anonsub :w { ? * } The non-lexically scoped declaration cannot specify a return type in front. The return type can only be specified as a trait in that case. [Update: These days the return type may be specified as part of the signature after a C<< --> >>. It's also possible to use a declarator in front of a declaration that introduces no name. And again, the C<:w> is no longer used in rules.] As in Perl 5, the difference between a package sub and an anonymous sub depends on whether you specify the C<< >>. If omitted, the declaration (which is not really a declaration in that case) generates and returns a closure. (Which may not I be a closure if it doesn't access any external lexicals, but we call them all closures anyway just in case...) A lexical subroutine is declared using either C or C: rule lexscope { my | our } This list doesn't include C or C because those are not declarators of lexical scope but rather operators that initiate dynamic scoping. See the section below on Lvalue subroutines for more about C and C. In both lexical and package declarations, the name of the subroutine is introduced by the keyword C, or one of its variants: rule subintro { sub | method | submethod | multi | rule | macro } A C participates in inheritance and always has an invocant (object or class). A C has an invocant but does not participate in inheritance. It's a sub pretending to be a method for the current class only. A C is a multimethod, that is, a method that is called like a subroutine or operator, but is dispatched based on the types of one or more of its arguments. [Update: These days C is just a modifier on C or C, but if you say C the C may be omitted since it's the default.] Another variant is the regex C, which is really a special kind of method; but in actuality rules probably get their own set of parse rules, since the body of a rule is a regex. I just put "rule" into as a placeholder of sorts, because I'm lazy. [Update: Rules are now split up into C, C, and C declarations. These differ in backtracking policy and whitespace matching. See S05.] A C is a subroutine that is called immediately upon completion of parsing. It has a default means of parsing arguments, or it may be bound to an alternate grammar rule to parse its arguments however you like. These syntactic forms correspond the various C types in the C type hierarchy: Code ____________|________________ | | Routine Block ________________|_______________ __|___ | | | | | | | | Sub Method Submethod Multi Rule Macro Bare Parametric The C/C distinction is fairly important, since you always C out of the current C, that is, the current C, C, C, C, C, or C. Also, the C<&_> variable refers to your current C. A C, whether C or C, is invisible to both of those notions. (It's not yet clear whether the C vs C distinction is useful. Some apparently C blocks are actually C if they refer to C<$_> internally, even implicitly. And a C block is just a C block with a signature of C<()>. More later.) [Update: There's no longer a Bare/Parametric distinction.] A C<< >> is a parenthesized signature: rule psignature :w { \( \) } And there is a variant that doesn't declare names: rule psiglet :w { \( \) } (We'll discuss "siglets" later in their own section.) It's possible to declare a subroutine in an lvalue or a signature as if it were an ordinary variable, in anticipation of binding the symbol to an actual subroutine later. Note this only works with an explicit name, since the whole point of declaring it in the first place is to have a name for it. On the other hand, the formal subroutine's parameters I named, hence they are specified by a C<< >> rather than a C<< >>: rule scopedsubvar :w { ? & ? * } rule unscopedsubvar :w { & ? * } If no C<< >> is supplied for such a declaration, it just uses whatever the signature of the bound routine is. So instead of: my sub foo (*@_) { print @_ } you could equivalently say: my &foo ::= sub (*@_) { print @_ }; (You may recall that C<::=> does binding at compile time. Then again, you may not.) If there is a C<< >>, however, it must be compatible with the signature of the routine that is bound to it: my &moo(Cow) ::= sub (Horse $x) { $x.neigh }; # ERROR =head3 "Pointy subs" "Pointy subs" declare a closure with an unparenthesized signature: rule pointysub :w { -\> } They may not take traits. =head3 Bare subs A bare block generates a closure: rule baresub :w { { .find_placeholders() } } A bare block declaration does not take traits (externally, anyway), and if there are any parameters, they must be specified with placeholder variables. If no placeholders are used, C<$_> may be treated as a placeholder variable, provided the surrounding control structure passes an argument to the the closure. Otherwise, C<$_> is bound as an ordinary lexical variable to the outer C<$_>. (C<$_> is also an ordinary lexical variable when explicit placeholders are used.) More on parameters below. But before we talk about parameters, we need to talk about types. =head2 Digression on types Well, what are types, anyway? Though known as a "typeless" language, Perl actually supports several built-in container types such as scalar, array, and hash, as well as user-defined, dynamically typed objects via C. Perl 6 will certainly support more types. These include some low-level storage types: bit int str num ref bool as well as some high-level object types: Bit Int Str Num Ref Bool Array Hash Code IO Routine Sub Method Submethod Macro Rule Block Bare Parametric Package Module Class Object Grammar List Lazy Eager (These lists should not be construed as exhaustive.) We'll also need some way of at least hinting at representations to the compiler, so we may also end up with types like these: int8 int16 int32 int64 uint8 uint16 uint32 uint64 Or maybe those are just extra C traits on a declaration somewhere. That's not important at this point. The important thing is that we're adding a generalized type system to Perl. Let us begin by admitting that it is the height of madness to add a type system to a language that is well-loved for being typeless. But mad or not, there are some good reasons to do just that. First, it makes it possible to write interfaces to other languages in Perl. Second, it gives the optimizer more information to think about. Third, it allows the S&M folks to inflict strongly typed compile-time semantics on each other. (Which is fine, as long as they don't inflict those semantics on the rest of us.) Fourth, a type system can be viewed as a pattern matching system for multi-method dispatch. Which basically boils down to the notion that it's fine for Perl to have a type system as long as it's optional. It's just another area where Perl 6 will try to have its cake and eat it too. This should not actually come as a surprise to anyone who has been following the development of Perl 5, since the grammatical slot for declaring a variable's effective type has been defined for some time now. In Perl 5 you can say: my Cat $felix; to declare a variable intended to hold a C object. That's nice, as far as it goes. Perl 6 will support the same syntax, but we'll have to push it much further than that if we're to have a type system that is good enough to specify interfaces to languages like C++ or Java. In particular, we have to be able to specify the types of composite objects such as arrays and hashes without resorting to class definitions, which are rather heavyweight--not to mention opaque. We need to be able to specify the types of individual function and method parameters and return values. Taken collectively, these parameter types can form the signature of a subroutine, which is one of the traits of the subroutine. And of course, all this has to be intuitively obvious to the naive user. Yeah, sure, you say. Well, let's see how far we can get with it. If the type system is too klunky for some particular use, people will simply avoid using it. Which is fine--that's why it's optional. First, let's clarify one thing that seems to confuse people frequently. Unlike some languages, Perl makes a distinction between the type of the variable, and the type of the value. In Perl 5, this shows up as the difference between overloading and tying. You overload the value, but you tie the variable. When you say: my Cat $felix; you are specifying the type of the I being stored, not the type of the I doing the storing. That is, C<$felix> must contain a reference to a C value, or something that "isa" C. The variable type in this case is just a simple scalar, though that can be changed by tying the variable to some class implementing the scalar variable operations. In Perl 6, the type of the variable is just one of the traits of the variable, so if you want to do the equivalent of a C to the C class, you say something like: my Cat $felix is Box; That declares your intent to store a C value into a C variable. (Whether the cat will then dead or alive (or dead|alive) depends on the definition of the C class, and whether the C object's side effects extend to the C value stored in it.) But by default: my Cat $felix; just means something like: my Cat $felix is Scalar; Likewise, if you say: my Cat @litter; it's like saying: my Cat @litter is Array; That is, C<@litter> is an ordinary array of scalar values that happen to be references to Cs. In the abstract, C<@litter> is a function that maps integers to cats. Likewise, my Cat %pet; is like: my Cat %pet is Hash; You can think of the C<%pet> hash as a function that maps cat names (strings) to cats. Of course, that's an oversimplification--for both arrays and hashes, subscripting is not the only operation. But it's the fundamental operation, so the declared type of the returned value reflects the return value of such a subscripted call. Actually, it's not necessarily the return type. It's merely a type that is I with the returned type. It would be better to declare: my Animal %pet; and then you could return a C or a C or a C, presuming all those are derived from C. You'd have to generalize it a bit further if you want to store your pet C. In the limit, you can just leave the type out. When you say: my %pet; you're really just saying: my Object %pet is Hash; ...except that you're not. We have to push it further than that, because we have to handle more complicated structures as well. When you say: my Cat @litter is Array; it's really shorthand for: my @litter is Array of Cat; That is, "C" is really a funny parameter that says what kind of C you have. If you like, you could even write it like this: my @litter is Array(returns => Cat) Likewise you might write: my %pet is Hash(keytype => Str, returns => Cat) and specify the key type of the hash. The "C" keyword is just syntactic sugar for specifying the return type of the previous storage class. So we could have my %pet is Hash of Array of Array of Hash of Array of Cat; which might really mean: my %pet is Hash(keytype => Str, returns => Array( returns => Array( returns => Hash( keytype => Str, returns => Array( returns => Cat))))) or some such. [Update: Type parameters are now written with square brackets, and we now distinguish the C property from the C property.] I suppose you could also write that as: my Array of Array of Hash of Array of Cat %pet; but for linguistic reasons it's probably better to keep the variable name near the left and put the long, heavy phrases to the right. (People tend to prefer to say the short parts of their sentences before the long parts--linguists call this the "end-weight" problem.) The C is implied by the C<%pet>, so you could leave out the "C" part and just say: my %pet of Array of Array of Hash of Array of Cat; Another possibility is: my Cat %pet is Hash of Array of Array of Hash of Array; That one reads kinda funny if you leave out the "C", though. Nevertheless, it says that we have this funny data structure that has multiple parameters that you can view as a funny function returning C. In fact, "C" is a synonym for "C". This is also legal: my @litter returns Cat; [Update: Not any more.] But the "C" keyword is mostly for use by functions: my Cat sub find_cat($name) {...} is the same as: my sub find_cat($name) returns Cat {...} This is more important for things like closures that have no "C" on the front: $closure = sub ($name) returns Cat {...} Though for the closure case, it's possible we could define some kind of non-C article to introduce a type unambiguously: $closure = a Camel sub ($name) {...} $closure = an Aardvark sub () {...} Presumably "C" or "C" is short for "anonymous". Which is more or less what the indefinite article means in English. [Update: You can just use C there and leave the name out.] However, we need C anyway in cases where the return value is complicated, so that you'd rather list it later (for end-weight reasons): my sub next_prisoner() returns (Nationality, Name, Rank, SerialNo) {...} Note that the return type is a signature much like the parameter types, though of course there are no formal parameter names on a return value. (Though there could be, I suppose.) We're calling such nameless signatures "siglets". [Update: It turns out that the C property just constrains the return type as seen by the routine, and not the return type seen by the rest of the world. Use the type prefix or arrow form to declare a return type that is seen by the rest of the world, and in particular any type inferencing engine. We call that the C type to distinguish it from the C type that is specified by the C property.] =head2 Stub declarations When you declare a subroutine, it can change how the rest of the current file (or string) is compiled. So there is some pressure to put subroutine declarations early. On the other hand, there are good reasons for putting subroutine definitions later in the file too, particularly when you have mutually recursive subroutines. Beyond that, the definition might not even be supplied until run time if you use some kind of autoloading mechanism. (We'll discuss autoloading in Apocalypse 10, Packages.) Perl 5 has long supported the notion of "forward" declarations or "stubs" via a syntax that looks like this: sub optimal; Perl 6 also supports stubbing, but instead you write it like this: sub optimal {...} That is, the stub is distinguished not by leaving the body of the function out, but by supplying a body that explicitly calls the "C<...>" operator (known affectionately as the "yada, yada, yada" operator). This operator emits a warning if you actually try to execute it. (It can also be made to pitch an exception.) There is no warning for redefining a C<{...}> body. We're moving away from the semicolon syntax in order to be consistent with the distinction made by other declarations: package Fee; # scope extends to end of file package Fee { ... } # scope extends over block module Fie; # scope extends to end of file module Fie { ... } # scope extends over block class Foe; # scope extends to end of file class Foe { ... } # scope extends over block To be consistent, a declaration like: sub foo; would therefore extend to the end of the file. But that would be confusing for historical reasons, so we disallow it instead, and you have to say: sub foo {...} [Update: Perl 6 also allows you to defer declaring your subroutine till later in the file, but only if the delayed declaration declares the sub to be parsed consistent with how a list operator would be parsed. Basically, any unrecognized "bareword" is assumed to be a provisional list operator that must be declared by the end of the current compilation unit.] =head2 Scope of subroutine names Perl 5 gives subroutine names two scopes. Perl 6 gives them four. =head3 Package scoped subs All named subs in Perl 5 have package scope. (The body provides a lexical scope, but we're not talking about that. We're talking about where the name of the subroutine is visible from.) Perl 6 provides by default a package-scoped name for "unscoped" declarations such as these: sub fee {...} method fie {...} submethod foe {...} multi foo {...} macro sic {...} Methods and submethods are ordinarily package scoped, because (just as in Perl 5) a class's namespace is kept in a package. =head3 Anonymous subs It's sort of cheating to call this a subroutine scope, because it's really more of a non-scope. Scope is a property of the I of a subroutine. Since closures and anonymous subs have no name, they naturally have no intrinsic scope of their own. Instead, they rely on the scope of whatever variable contains a reference to them. The only way to get a lexically scoped subroutine name in Perl 5 was by indirection: my $subref = sub { dostuff(@_) } &$subref(...) But that doesn't actually give you a lexically scoped name that is equivalent to an ordinary subroutine's name. Hence, Perl 6 also provides... =head3 Lexically scoped subs You can declare "scoped" subroutines by explicitly putting a C or C on the front of the declaration: my sub privatestuff { ... } our sub semiprivatestuff { ... } Both of these introduce a name into the current lexical scope, though in the case of C this is just an alias for a package subroutine of the same name. (As with other uses of C, you might want to introduce a lexical alias if your strictness level prohibits unqualified access to package subroutines.) You can also declare lexically scoped macros: my macro sic { ... } =head3 Global scoped subs Perl 6 also introduces the notion of completely global variables that are visible from everywhere they aren't overridden by the current package or lexical scope. Such variables are named with a leading C<*> on the identifier, indicating that the package prefix is a wildcard, if you will. Since subroutines are just a funny kind of variable, you can also have global subs: sub *print (*@list) { $*DEFOUT.print(@list) } } In fact, that's more-or-less how some built-in functions like C could be implemented in Perl 6. (Methods like C<$*DEFOUT.print()> are a different story, of course. They're defined off in a class somewhere. (Unless they're multimethods, in which case they could be defined almost anywhere, because multimethods are always globally scoped. (In fact, most built-ins including C will be multimethods, not subs. (But we're getting ahead of ourselves...)))) =head2 Signatures One of Perl's strong points has always been the blending of positional parameters with variadic parameters. "Variadic" parameters are the ones that I. They're the "...And The Rest" list of values that many functions--like C, C, and C--have at the end of their call. Whereas positional parameters generally tell a function I to do its job, variadic parameters are most often used to pass the arbitrary sequences of data the function is supposed to do its job on/with/to. In Perl 5, when you unpack the arguments to a C like so: my ($a, $b, $c, @rest) = @_; you are defining three positional parameters, followed by a variadic list. And if you give the sub a prototype of C<($$$@)> it will force the first three parameters to be evaluated in scalar context, while the remaining arguments are evaluated in list context. The big problem with the Perl 5 solution is that the parameter binding is done at run time, which has run-time costs. It also means the metadata is not readily available outside the function body. We could just as easily have written it in some other form like: my $a = shift; my $b = shift; my $c = shift; and left the rest of the arguments in C<@_>. Not only is this difficult for a compiler to analyze, but it's impossible to get the metadata from a stub declaration; you have to have the body defined already. The old approach is very flexible, but the cost to the user is rather high. Perl 6 still allows you to access the arguments via C<@_> if you like, but in general you'll want to hoist the metadata up into the declaration. Perl 6 still fully supports the distinction between positional and variadic data--you just have to declare them differently. In general, variadic items must follow positional items both in declaration and in invocation. In turn, there are at least three kinds of positional parameters, and three kinds of variadic parameters. A declaration for all six kinds of parameter won't win a beauty contest, but might look like this: method x ($me: $req, ?$opt, +$namedopt, *%named, *@list) {...} [Update: that currently looks like this: method x ($me: $req, $opt?, :$namedopt, *%named, *@list) {...} ] Of course, you'd rarely write all of those in one declaration. Most declarations only use one or two of them. Or three or four... Or five or six... There is some flexibility in how you pass some of these parameters, but the ordering of both formal parameters and actual arguments is constrained in several ways. For instance, positional parameters must precede non-positional, and required parameters must precede optional. Variadic lists must be attached either to the end of the positional list or the end of the named parameter list. These constraints serve a number of purposes: =over 4 =item * They avoid user confusion. =item * They enable the system to implement calls efficiently. =item * Perhaps most importantly, they allow interfaces to evolve without breaking old code. =back Since there are constraints on the ordering of parameters, similar parameters tend to clump together into "zones". So we'll call the C, C<+>, and C<*> symbols you see above "zone markers". The underlying metaphor really is very much like zoning regulations--you know, the ones where your city tells you what you may or may not do on a chunk of land you think you own. Each zone has a set of possible uses, and similar zones often have overlapping uses. But you're still in trouble if you put a factory in the middle of a housing division, just as you're in trouble if you pass a positional argument to a formal parameter that has no position. I was originally going to go with a semicolon to separate required from optional parameters (as Perl 5 uses in its prototypes), but I realized that it would get lost in the traffic, visually speaking. It's better to have the zone markers line up, especially if you decide to repeat them in the vertical style: method action ($self: int $x, int ?$y, int ?$z, Adverb +$how, Beneficiary +$for, Location +$at is copy, Location +$toward is copy, Location +$from is copy, Reason +$why, *%named, *@list ) {...} So optional parameters are all marked with zone markers. In this section we'll be concentrating on the declaration's syntax rather than the call's syntax, though the two cannot be completely disintertwingled. The declaration syntax is actually the more complicated of the two for various good reasons, so don't get too discouraged just yet. =head3 Positional parameters The three positional parameter types are the invocant, the required parameters, and the optional positional parameters. (Note that in general, positional parameters may also be called using named parameter notation, but they must be declared as positional parameters if you wish to have the I