Apocalypse 6
by Larry Wall
|
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
Editor's Note: this Apocalypse is out of date and remains here for historic reasons. See Synopsis 06 for the latest information.
Defaults
Default values are also traits, but are written as assignments and must come at the end of the formal parameter for psychological reasons.
rule defval :w { \= <item> }
That is:
sub trim ( Str $_ is rw, Rule ?$remove = /\s+/ ) {
s:each/^ <$remove> | <$remove> $//;
}
lets you call trim as either:
trim($input);
or:
trim($input, /\n+/);
It's very important to understand that the expression denoted by
item is evaluated in the lexical scope of the subroutine definition,
not of the caller. If you want to get at the lexical scope of the
caller, you have to do it explicitly (see CALLER:: below). Note
also that an item may not contain unbracketed commas, or the parser
wouldn't be able to reliably locate the next parameter declaration.
Although the default looks like an assignment, it isn't one. Nor is
it exactly equivalent to //=, because the default is set only
if the parameter doesn't exist, not if it exists but is undefined.
That is, it's used only if no argument is bound to the parameter.
An rw parameter may only default to a valid lvalue. If you find
yourself wanting it to default to an ordinary value because it's
undefined, perhaps you really want //= instead:
sub multprob ($x is rw, $y) {
$x //= 1.0; # assume undef means "is certain"
$x *= $y;
}
Syntactically, you can put a default on a required parameter, but it
would never be used because the argument always exists. So semantic
analysis will complain about it. (And I'd rather not say that adding
a default implies it's optional without the ? zone marker.)
Formal parameter types
Formal parameters may have any type that any other variable may have, though particular parameters may have particular restrictions. An invocant needs to be an object of an appropriate class or subclass, for instance. As with ordinary variable declarations the type in front is actually the return type, and you can put it afterwards if you like:
sub foo (int @array is rw) {...}
sub foo (@array of int is rw) {...}
sub foo (@array is Array of int is rw) {...}
The type of the actual argument passed must be compatible with (but not necessarily identical to) the formal type. In particular, for methods the formal type will often indicate a base class of the actual's derived class. People coming from C++ must remember that all methods are "virtual" in Perl.
Closure parameters are typically declared with &:
sub mygrep (&block, *@list is rw) {...}
Within that subroutine, you can then call block() as an ordinary
subroutine with a lexically scoped name. If such a parameter is
declared without its own parameter signature, the code makes no
assumptions about the actual signature of the closure supplied as
the actual argument. (You can always inspect the actual signature
at run time, of course.)
You may, however, supply a signature if you like:
sub mygrep (&block($foo), *@list is rw) {
block(foo => $bar);
}
With an explicit signature, it would be error to bind a block to
&block that is not compatible. We're leaving "compatible" undefined
for the moment, other than to point out that the signature doesn't have
to be identical to be compatible. If the actual subroutine accepted
one required parameter and one optional, it would work perfectly fine,
for instance. The signature in mygrep is merely specifying what
it requires of the subroutine, namely one positional argument named
"$foo". (Conceivably it could even be named something different
in the actual routine, provided the compiler turns that call into a
positional one because it thinks it already knows the signature.)
Calling subroutines
The typical subroutine or method is called a lot more often than
it is declared. So while the declaration syntax is rather ornate,
we strive for a call syntax that is rather simple. Typically it
just looks like a comma-separated list. Parentheses are optional on
predeclared subroutine calls, but mandatory otherwise. Parentheses
are mandatory on method calls with arguments, but may be omitted
for argumentless calls to methods such as attribute accessors.
Parentheses are optional on multimethod and macro calls because they
always parse like list operators. A rule may be called like a method
but is normally invoked within a regex via the <rule> syntax.
As in Perl 5, within the list there may be an implicit transition
from scalar to list context. For example, the declaration of the
standard push built-in in Perl 6 probably looks like this:
multi *push (@array, *@list) {...}
but you still generally call it as you would in Perl 5:
push(@foo, 1, 2, 3);
This call has two of the three kinds of call arguments. It has one
positional argument, followed by a variadic list. We could imagine
adding options to push sometime in the future. We could define
it like this:
multi *push (@array, ?$how, *@list) {...}
That's just an optional positional parameter, so you'd call it like this:
push(@foo, "rapidly", 1,2,3)
But that won't do, actually, since we used to allow the list to
start at the end of the positional parameters, and any pre-existing
push(@foo,1,2,3) call to the new declaration would end up mapping
the "1" onto the new optional parameter. Oops...
If instead we force new parameters to be in named notation, like this:
multi *push (@array, *@list, +$how) {...}
tèen we can say:
push(@foo, how => "rapidly", 1,2,3)and it's no longer ambiguous. Since dhow is iî the named-only zone,
it can never be set positionally, and the old calls to:
push(@foo, 1,2,3);
still work fine, because *@list is still at the end of the
positional parameter zone. If we instead declare that:
multi *push (@array, +$how, *@list) {...}
we could still say:
push(@foo, how => "rapidly", 1,2,3)
but this becomes illegal:
push(@foo, 1,2,3);
because the slurpy array is in the named-only zone. We'll need an explicit way to indicate the start of the list in this case. I can think of lots of (mostly bad) ways. You probably can too. We'll come back to this...
Actual arguments
So the actual arguments to a Perl function are of three kinds: positional, named, and list. Any or all of these parts may be omitted, but whenever they are there, they must occur in that order. It's more efficient for the compiler (and less confusing to the programmer) if all the positional arguments come before all the non-positional arguments in the list. Likewise, the named arguments are constrained to occur before the list arguments for efficiency--otherwise the implementation would have to scan the entire list for named arguments, and some lists are monstrous huge.
We'd call these three parts "zones" as well, but then people would get them confused with our six declarative zones. In fact, extending the zoning metaphor a bit, our three parts are more like houses, stores, and factories (real ones, not OO ones, sheesh). These are the kinds of things you actually find in residential, commercial, and industrial zones. Similarly, you can think of the three different kinds of argument as the things you're allowed to bind in the different parameter zones.
A house is generally a scalar item that is known for its position; after all, "there's no place like home". Um, yeah. Anyway, we usually number our houses. In the US, we don't usually name our houses, though in the UK they don't seem to mind it.
A store may have a position (a street number), but usually we refer to stores by name. "I'm going out to Fry's" does not refer to a particular location, at least not here in Silicon Valley. "I'm going out to McDonald's" doesn't mean a particular location anywhere in the world, with the possible exception of "not Antarctica".
You don't really care exactly where a factory is--as long as it's not in your back yard--you care what it produces. The typical factory is for mass producing a series of similar things. In programming terms, that's like a generator, or a pipe...or a list. And you mostly worry about how you get vast quantities of stuff into and out of the factory without keeping the neighbors awake at night.
So our three kinds of arguments map onto the various parameter zones in a similar fashion.
The positional arguments
Obviously, actual positional arguments are mapped onto the formal
parameters in the order in which the formal positional parameters
are declared. Invocant parameters (if any) must match invocant
arguments, the required parameters match positional arguments, and
then any additional non-named arguments are mapped onto the optional
positional parameters. However, as soon as the first named argument is
seen (that cannot be mapped to an explicitly typed Pair or Hash
parameter) this mapping stops, and any subsequent positional parameters
may only be bound by name.
The named arguments
After the positional argument part, you may pass as many named pairs as you like. These may bind to any formal parameter named in the declaration, whether declared as positional or named. However, it is erroneous to simultaneously bind a parameter both by position and by name. Perl may (but is not required to) give you a warning or error about this. If the problem is ignored, the positional parameter takes precedence, since the name collision might have come in by accident as a result of passing extra arguments intended for a different routine. Problems like this can arise when passing optional arguments to all the base classes of the current class, for instance. It's not yet clear how fail-soft we should be here.
Named arguments can come in either as Pair or Hash references.
When parameter mapper sees an argument that is neither a Pair nor a
Hash, it assumes it's the end of the named part and the beginning of
the list part.
All unbound named arguments are bound to elements of the slurpy hash,
if one was declared. If no slurpy hash is declared, an exception is
thrown (although some standard methods, like BUILD, will provide
an implicitly declared slurpy hash--known as %_ by analogy
to @_--to handle surplus named arguments).
At the end of named argument processing, any unmapped optional
parameter ends up with the value undef unless a default value is
declared for it. Any unmapped required parameter throws an exception.
The slurpy array
All remaining arguments are bound to the slurpy array, if any. If no
slurpy array is specified, any remaining arguments cause an exception
to be thrown. (You only get an implicit *@_ slurpy array when the
signature is omitted entirely. Otherwise we could never validly give
the error "Too many arguments".)
No argument processing is done on this list. If you go back to using named pairs at the end of the list, for instance, you'll have to pop those off yourself. But since the list is potentially very long, Perl isn't going to look for those on your behalf.
Indeed, the list could be infinitely long, and maybe even a little longer than that. Perl 5 always flattens lists before calling the subroutine. In Perl 6, list flattening is done lazily, so a list could contain several infinite entries:
print(1..Inf, 1..Inf);
That might eventually give the print function heartburn, of course...
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 |

