Author: larry
Date: Wed Sep 20 22:07:47 2006
New Revision: 12284
Modified:
doc/trunk/design/syn/S02.pod
doc/trunk/design/syn/S03.pod
doc/trunk/design/syn/S06.pod
doc/trunk/design/syn/S12.pod
Log:
The | sigil and operator.
Modified: doc/trunk/design/syn/S02.pod
==============================================================================
--- doc/trunk/design/syn/S02.pod (original)
+++ doc/trunk/design/syn/S02.pod Wed Sep 20 22:07:47 2006
@@ -12,9 +12,9 @@
Maintainer: Larry Wall <[EMAIL PROTECTED]>
Date: 10 Aug 2004
- Last Modified: 18 Sept 2006
+ Last Modified: 20 Sept 2006
Number: 2
- Version: 69
+ Version: 70
This document summarizes Apocalypse 2, which covers small-scale
lexical items and typological issues. (These Synopses also contain
@@ -670,6 +670,7 @@
@ ordered array
% unordered hash (associative array)
& code/rule/token/regex
+ | capture/arguments/match
:: package/module/class/role/subset/enum/type/grammar
@@ multislice view of @
@@ -817,15 +818,22 @@
$$args; # same as "$args as Scalar" or "Scalar($args)"
@$args; # same as "$args as Array" or "Array($args)"
%$args; # same as "$args as Hash" or "Hash($args)"
+ |$args; # all of the above
When cast into an array, you can access all the positional arguments; into a
hash, all named arguments; into a scalar, its invocant.
+When stored in a variable using the C<|> sigil, the capture autointerpolates
+into argument lists much like C<@> autoflattens into lists:
+
+ |args := \($a, @b, :option($c));
+ somefunc(|args); # same as somefunc($a, @b, :option($c))
+
All prefix sigil operators accept one positional argument, evaluated in
scalar context as a rvalue. They can interpolate in strings if called with
parentheses. The special syntax form C<$()> translates into C<$( $/ )>
to operate on the current match object; the same applies to C<@()>, C<%()> and
-C<*()> forms.
+C<|()> forms.
C<Capture> objects fill the ecological niche of references in Perl 6.
You can think of them as "fat" references, that is, references that
Modified: doc/trunk/design/syn/S03.pod
==============================================================================
--- doc/trunk/design/syn/S03.pod (original)
+++ doc/trunk/design/syn/S03.pod Wed Sep 20 22:07:47 2006
@@ -12,9 +12,9 @@
Maintainer: Larry Wall <[EMAIL PROTECTED]>
Date: 8 Mar 2004
- Last Modified: 16 Sep 2006
+ Last Modified: 20 Sept 2006
Number: 3
- Version: 66
+ Version: 67
=head1 Changes to Perl 5 operators
@@ -65,7 +65,8 @@
argument, and C<+> imposes a numeric (C<Num>) context (as opposed
to being a no-op in Perl 5). Along the same lines, C<?> imposes
a boolean (C<Bool>) context, and the C<[,]> list operator imposes
-a function-arguments (C<Capture>) context on its arguments.
+a function-arguments (C<Capture>) context on its arguments (as does
+the C<|> sigil when used as an operator).
Unary sigils impose the container context implied by their sigil.
As with Perl 5, however, C<$$foo[bar]> parses as C<( $($foo) )[bar]>,
so you need C<$($foo[bar])> to mean the other way.
@@ -1295,11 +1296,14 @@
interpolator, by casting its operands to C<Capture> objects
and inserting them into the current argument list.
-It can be used to interpolate an C<Array> or C<Hash> into the current
-call, as positional and named arguments respectively.
+The C<|> capture sigil may also be used for this when you want to
+interpolate a single item.
+
+Either of these can be used to interpolate an C<Array> or C<Hash>
+into the current call, as positional and named arguments respectively.
Note that those arguments still must comply with the subroutine's
-signature, but the presence of C<[,]> defers that test until run time for
+signature, but the presence of C<|> or C<[,]> defers that test until run time
for
that argument (and for any subsequent arguments):
my @args = [EMAIL PROTECTED], @bar;
@@ -1312,7 +1316,16 @@
as is this:
my $args = \(@foo, @bar); # construct a Capture object
- push [,] @$args;
+ push |$args;
+
+The C<|> sigil functions as a unary form of the C<[,]>
+list operator, so we could have written the earlier example as:
+
+ my @args = [EMAIL PROTECTED], @bar;
+ push |@args;
+
+To the extent possible, the C<|> will treat its argument as
+a C<Capture> even if it isn't.
In list context, a C<Scalar> holding an C<Array> object does not flatten.
Hence
@@ -1320,15 +1333,16 @@
push @foo, $bar;
merely pushes a single C<Array> object onto C<@foo>. You can
-explicitly flatten it in either of these ways:
+explicitly flatten it in one of these ways:
push @foo, @$bar;
push @foo, $bar[];
+ push @foo, |$bar;
-Those two forms work because the slurpy array in C<push>'s signature
+Those three forms work because the slurpy array in C<push>'s signature
flattens the C<Array> object into a list argument.
-Note that those two forms also allow you to specify list context on
+Note that the first two forms also allow you to specify list context on
assignment:
@$bar = 1,2,3;
@@ -1351,18 +1365,20 @@
as well as the C<< <> >>, C<< .<> >>, C<«»>, and C<.«»> constant and
interpolating slice subscripting forms.
-The C<[,]> operator interpolates lazily for C<Array> and C<Range> objects.
+The C<[,]> and C<|> operators interpolate lazily for C<Array> and C<Range>
objects.
To get an immediate interpolation like Perl 5 does, add the C<eager> list
operator:
func([,] 1..Inf); # works fine
func([,] eager 1..Inf); # never terminates
-To interpolate a function's return value, you must say:
+To interpolate a function's return value, you must say one of:
push [,] func();
+ push |(func());
+ push |func(); # WRONG, would parse as (|func).()
-Within the argument list of a C<[,]>, function return values are
+Within such an argument list, function return values are
automatically exploded into their various parts, as if you'd said:
my \$capture := func();
@@ -1375,12 +1391,17 @@
as if its colon changed back to a comma.
If you already have a capture variable, you can interpolate all of
-its bits at once using the C<< prefix:<=> >> operator, which serves
-to iterate or dereference a scalar that would otherwise stay packed
-into its scalar value. The above is equivalent to:
+its bits at once using the C<< prefix:<|> >> operator (really a sigil).
my \$capture := func();
- push [,] =$capture;
+ push |$capture;
+
+Or you can use the bare sigiled forms:
+
+ my |capture := func();
+ push |capture;
+
+Bare lvalue capture variables may only be bound, not assigned.
=head1 Feed operators
@@ -1551,7 +1572,7 @@
method postfix .meth .+ .? .* .() .[] .{} .<> .«» .:: .= .^
autoincrement ++ --
exponentiation **
- symbolic unary ! + - ~ ? $ @ % & +^ ~^ ?^ \ ^ =
+ symbolic unary ! + - ~ ? $ @ % & | +^ ~^ ?^ \ ^ =
multiplicative * / % x xx +& +< +> ~& ~< ~> ?&
additive + - ~ +| +^ ~| ~^ ?| ?^
junctive and (all) &
Modified: doc/trunk/design/syn/S06.pod
==============================================================================
--- doc/trunk/design/syn/S06.pod (original)
+++ doc/trunk/design/syn/S06.pod Wed Sep 20 22:07:47 2006
@@ -373,23 +373,21 @@
doit :123<now>; # always a positional arg
Going the other way, pairs intended as named arguments that don't look
-like pairs must be introduced with the C<[,]> reduction operator:
+like pairs must be introduced with the C<[,]> reduction operator or
+the C<|> capture sigil:
$pair = :when<now>;
- doit $pair,1,2,3; # always a positional arg
- doit [,] %$pair,1,2,3; # always a named arg
- doit [,] %(get_pair()),1,2,3; # always a named arg
- doit [,] %('when' => 'now'),1,2,3; # always a named arg
-
-Note that, to apply C<[,]> to a single arg you may need to use parentheses.
-In general it doesn't matter.
+ doit $pair,1,2,3; # always a positional arg
+ doit |%$pair,1,2,3; # always a named arg
+ doit |%(get_pair()),1,2,3; # always a named arg
+ doit |%('when' => 'now'),1,2,3; # always a named arg
Likewise, if you wish to pass a hash and have its entries treated as
-named arguments, you must dereference it with a C<[,]>:
+named arguments, you must dereference it with a C<[,]> or C<|>:
%pairs = {:when<now> :what<any>};
doit %pairs,1,2,3; # always a positional arg
- doit [,](%pairs),1,2,3; # always named args
+ doit |%pairs,1,2,3; # always named args
Variables with a C<:> prefix in rvalue context autogenerate pairs, so you
can also say this:
@@ -465,7 +463,7 @@
parameters, similar to how hash constructors work:
# Allow "x" and "y" in %defaults to be overridden
- f( [,](%defaults), x => 1, y => 2 );
+ f( |%defaults, x => 1, y => 2 );
=head2 Invocant parameters
@@ -699,41 +697,39 @@
=head2 Argument list binding
The underlying C<Capture> object may be bound to a single scalar
-parameter marked with a C<\>.
+parameter marked with a C<|> sigil.
sub bar ($a,$b,$c,:$mice) { say $mice }
- sub foo (\$args) { say $args.perl; &bar.call($args); }
+ sub foo (|args) { say |args.perl; &bar.callargs(|args); }
-The C<.call> method of C<Code> objects accepts a single C<Capture>
-object, and calls it without introducing a C<CALLER> frame.
+The C<.callargs> method of C<Code> objects accepts an argument list,
+(which can be specified as a Capture object as above), and calls it
+without introducing an official C<CALLER> frame.
foo 1,2,3,:mice<blind>; # says "\(1,2,3,:mice<blind>)" then "blind"
-It is allowed to specify a return type:
-
- sub foo (\$args --> Num) { ... }
+It is allowed to specify additional parameters. The Capture binding merely
+takes a snapshot of what's left of the Capture at that point and then
+continues binding as if the Capture parameter weren't there:
-Apart from that, no other parameters are allowed in the signature
-after the C<Capture>. Parameters before the C<Capture> either do not show up
in
-the C<Capture> or are marked as already bound somehow. In other words,
-parameters are bound normally up to the C<Capture> parameter, and then
-C<\$args> takes a snapshot of the remaining input without further
-attempts at binding.
+ sub compare (|args Num $x, Num $y --> Bool) { ... }
=head2 Flattening argument lists
The reduce operator C<[,]> casts each of its arguments to a C<Capture>
object, then splices each of those captures into the argument list
-it occurs in.
+it occurs in. The unary C<|> sigil has the same effect on a single
+argument.
Casting C<Capture> to C<Capture> is a no-op:
[,](\(1, x=>2)); # Capture, becomes \(1, x=>2)
+ |(\(1, x=>2)); # Capture, becomes \(1, x=>2)
C<Pair> and C<Hash> become named arguments:
- [,](x=>1); # Pair, becomes \(x=>1)
- [,]{x=>1, y=>2}; # Hash, becomes \(x=>1, y=>2)
+ |(x=>1); # Pair, becomes \(x=>1)
+ |{x=>1, y=>2}; # Hash, becomes \(x=>1, y=>2)
C<List> (also C<Seq>, C<Range>, etc.) are simply turned into
positional arguments:
@@ -750,7 +746,7 @@
foo(1,2,3); # okay: three args found
foo(@onetothree); # error: only one arg
- foo([,[EMAIL PROTECTED]); # okay: @onetothree flattened to three
args
+ foo(|@onetothree); # okay: @onetothree flattened to three args
The C<[,]> operator flattens lazily -- the array is flattened only if
flattening is actually required within the subroutine. To flatten before
@@ -1922,7 +1918,7 @@
On the caller's end, the C<Capture> is interpolated into any new argument list
much like an array would be, that is, as a scalar in scalar context, and as a
list in list context. This is the default behavior, but as with an array, the
-caller may use C<< prefix:<[,]> >> to inline the returned values as part of the
+caller may use C<< prefix:<[,]> >> or the C<|> sigil to inline the returned
values as part of the
new argument list. The caller may also bind the returned C<Capture> directly.
=head2 The C<caller> function
@@ -2081,16 +2077,20 @@
=head2 Wrapping
Every C<Routine> object has a C<.wrap> method. This method expects a single
-C<Code> argument. Within the code, the special C<call> function will invoke
-the original routine, but does not introduce a C<CALLER> frame:
+C<Code> argument. Within the code, the special C<call> and C<callargs>
functions will invoke
+the original routine, but do not introduce an official C<CALLER> frame:
sub thermo ($t) {...} # set temperature in Celsius, returns old value
# Add a wrapper to convert from Fahrenheit...
- $handle = &thermo.wrap( { call( ($^t-32)/1.8 ) } );
+ $handle = &thermo.wrap( { callargs( ($^t-32)/1.8 ) } );
+
+The C<callargs> function lets you pass your own arguments to the wrapped
+function. The C<call> function takes no arguments and implicitly passes
+the original argument list through unchanged.
The call to C<.wrap> replaces the original C<Routine> with the C<Code>
-argument, and arranges that the call to C<call> invokes the previous
+argument, and arranges that the call to C<call> or C<callargs> invokes the
previous
version of the routine. In other words, the call to C<.wrap> has more
or less the same effect as:
@@ -2112,29 +2112,35 @@
# Add a wrapper to convert from Kelvin
# wrapper self-unwraps at end of current scope
- temp &thermo.wrap( { call($^t + 273.16) } );
+ temp &thermo.wrap( { callargs($^t + 273.16) } );
-The entire argument list may be captured by the C<\$args> parameter.
-It can then be passed to C<call> as C<[,] =$args>:
+The entire argument list may be captured by binding to a Capture parameter.
+It can then be passed to C<callargs> using that name:
# Double the return value for &thermo
- &thermo.wrap( -> \$args { call([,] =$args) * 2 } );
+ &thermo.wrap( -> |args { callargs(|args) * 2 } );
+
+In this case only the return value is changed.
The wrapper is not required to call the original routine; it can call another
C<Code> object by passing the C<Capture> to its C<call> method:
# Transparently redirect all calls to &thermo to &other_thermo
- &thermo.wrap( -> \$args { &other_thermo.call($args) } );
+ &thermo.wrap( -> |args { &other_thermo.callargs(|args) } );
+
+or more briefly:
+
+ &thermo.wrap( { &other_thermo.call } );
-Outside a wrapper, C<call> implicitly calls the next-most-likely method
-or multi-sub; see S12 for details.
+Outside a wrapper, the various C<call> functions and methods implicitly
+call the next-most-likely method or multi-sub; see S12 for details.
As with any return value, you may capture the returned C<Capture> of C<call>
by binding:
- my \$retval := call([,] =$args);
+ my |retval := callargs(|args);
... # postprocessing
- return [,] =$retval;
+ return |retval;
=head2 The C<&?ROUTINE> object
@@ -2584,7 +2590,7 @@
and pass the resulting C<Match> object as a C<Capture> to C<MAIN>:
@*ARGS ~~ /<MyGrammar::top>/;
- MAIN([,] =$/);
+ MAIN(|$/);
exit;
sub MAIN ($frompart, $topart, [EMAIL PROTECTED]) {
Modified: doc/trunk/design/syn/S12.pod
==============================================================================
--- doc/trunk/design/syn/S12.pod (original)
+++ doc/trunk/design/syn/S12.pod Wed Sep 20 22:07:47 2006
@@ -12,9 +12,9 @@
Maintainer: Larry Wall <[EMAIL PROTECTED]>
Date: 27 Oct 2004
- Last Modified: 14 Sept 2006
+ Last Modified: 20 Sept 2006
Number: 12
- Version: 26
+ Version: 27
=head1 Overview
@@ -1165,7 +1165,7 @@
Since the method name (but nothing else) is known at class construction
time, the following C<.wag> method is autogenerated for you:
- method wag ([EMAIL PROTECTED] is context(Lazy)) { $!tail.wag([,] @args) }
+ method wag ([EMAIL PROTECTED] is context(Lazy)) { $!tail.wag(|@args) }
You can specify multiple method names:
@@ -1175,7 +1175,7 @@
has been initialized to an object of a type supporting the method,
such as by:
- has Tail $.tail handles 'wag' = { .new([,] %_) };
+ has Tail $.tail handles 'wag' = { .new(|%_) };
Note that putting a C<Tail> type on the attribute does not necessarily
mean that the method is always delegated to the C<Tail> class.