Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[svn:perl6-synopsis] r12284 - doc/trunk/design/syn

6 views
Skip to first unread message

la...@cvs.perl.org

unread,
Sep 21, 2006, 1:07:48 AM9/21/06
to perl6-l...@perl.org
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 <la...@wall.org>
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 <la...@wall.org>
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 = \@foo, @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 = \@foo, @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([,]@onetothree); # 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, *@rest) {

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 <la...@wall.org>
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 (*@args is context(Lazy)) { $!tail.wag([,] @args) }
+ method wag (*@args 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.

Aaron Sherman

unread,
Sep 21, 2006, 10:29:57 AM9/21/06
to Larry Wall, perl6-l...@perl.org
la...@cvs.develooper.com wrote:

> Maintainer: Larry Wall <la...@wall.org>
> Date: 10 Aug 2004
> - Last Modified: 18 Sept 2006
> + Last Modified: 20 Sept 2006
> Number: 2
> - Version: 69
> + Version: 70

> + | capture/arguments/match

> + |$args; # all of the above

I'll read that as "conversation terminated".

Can you please update S03's "Junctive operators" section to note how the
ambiguity of the following are resolved:

a|$b
a | $b
a |$b

I presume that it will be based on whitespace, but they could also be
based on an inspection of a's signature (if a takes no parameters, then
the only useful meaning of C<a|$b> is C<infix:<|>(a(), $b)>, I think).

I further presume that such an update will be required for the pugs/v6
team to correctly implement this.

Larry Wall

unread,
Sep 21, 2006, 12:11:29 PM9/21/06
to perl6-l...@perl.org
On Thu, Sep 21, 2006 at 10:29:57AM -0400, Aaron Sherman wrote:
: I'll read that as "conversation terminated".

The conversation is never terminated. However, every now and then I
make feeble attempts to be decisive. :)

: Can you please update S03's "Junctive operators" section to note how the

: ambiguity of the following are resolved:
:
: a|$b
: a | $b
: a |$b
:
: I presume that it will be based on whitespace, but they could also be
: based on an inspection of a's signature (if a takes no parameters, then
: the only useful meaning of C<a|$b> is C<infix:<|>(a(), $b)>, I think).

There's no whitespace dwimmery here. Either 'a' takes an argument list or
it doesn't, based on its signature. If it doesn't, all those are infix:<|>.
If it does, they are all prefix:<|>, except that we specifically outlaw
the first; list operators in Perl 6 require a space after them.

: I further presume that such an update will be required for the pugs/v6

: team to correctly implement this.

Don't think so. The situation is exactly analogous to:

a+$b
a + $b
a +$b

and even more exactly analogous to:

a%$b
a % $b
a %$b

The cultural ambiguity is also being reduced insofar as we're trying
to discourage use of bare constants in favor of sigilled constants.
If you see a bare function name you should generally assume it
has arguments in Perl 6. We could probably go as far as to issue
an optional warning on the middle cases above based on whitespace
dwimmery and on whether the program gets in trouble later. But it
would be a mistake to base the actual parsing on that. That's the sort
of trick Perl 5 would have attempted, and I hope I know better now.

Larry

Mark J. Reed

unread,
Sep 21, 2006, 12:16:26 PM9/21/06
to perl6-l...@perl.org
On 9/21/06, Larry Wall <la...@wall.org> wrote:
> : note how the ambiguity of the following are resolved:

> :
> : a|$b
> : a | $b
> : a |$b
> :

> Don't think so. The situation is exactly analogous to:
>


> a%$b
> a % $b
> a %$b
>
> The cultural ambiguity is also being reduced insofar as we're trying
> to discourage use of bare constants in favor of sigilled constants.

Which means that argumentless subroutine calls will presumably be rare
in P6 code, but what about methods? Methods with no arguments (apart
from the invocant) will always be commonplace, and it seems to me that
you have exactly the same ambiguity there:

$o.a%$b
$o.a % $b
$o.a %$b

--
Mark J. Reed <mark...@mail.com>

Larry Wall

unread,
Sep 21, 2006, 12:26:40 PM9/21/06
to perl6-l...@perl.org
On Thu, Sep 21, 2006 at 12:16:26PM -0400, Mark J. Reed wrote:
: Which means that argumentless subroutine calls will presumably be rare

: in P6 code, but what about methods? Methods with no arguments (apart
: from the invocant) will always be commonplace, and it seems to me that
: you have exactly the same ambiguity there:
:
: $o.a%$b
: $o.a % $b
: $o.a %$b

A method never takes arguments unless you use : or (), so those are
all infix. The design team worked Really Hard to get rid of that
particular ambiguity in Perl 6. Argumentless methods parse more
like variables than like functions.

Incidentally, this is why all the optional arg functions that default
to $_ turned into methods, so you have use .print if you want to print
$_ by default. Unlike a bare "print", a ".print" doesn't expect more
arguments unless you put : or (), so it simplifies parsing greatly.

Larry

Mark J. Reed

unread,
Sep 21, 2006, 12:33:00 PM9/21/06
to perl6-l...@perl.org
On 9/21/06, Larry Wall <la...@wall.org> wrote:
> A method never takes arguments unless you use : or (), so those are
> all infix.

Well, all righty then. Yay for unambiguity! Or disambiguation. Or
nonambiguosity. Or whatever...

> The design team worked Really Hard to get rid of that particular ambiguity in Perl 6.

Thank you, design team.

Aaron Sherman

unread,
Sep 21, 2006, 12:34:13 PM9/21/06
to perl6-l...@perl.org
All sounds good up to:

Larry Wall wrote:

> The cultural ambiguity is also being reduced insofar as we're trying
> to discourage use of bare constants in favor of sigilled constants.
> If you see a bare function name you should generally assume it
> has arguments in Perl 6.

Well, in that case, should pi, e, et al. become $pi, $e, @et al.? ;)

Seriously, though, I think we discussed this before, and we kept those
constants as bare, but if there's a cultural shift, then those would
probably be its poster-children. I'm also in favor of the $π type
Unicode equivalents for uniformity. Boolean constants are more
questionable, as is the zeroary undef, which is pretty hard-coded in the
brain of the average Perl programmer.

Right now, in the Math::Basic API doc, we have:

------------------------

=head2 Constants

To export the constants provided by C<Math::Basic> use the C<:constants>
tag when importing:

use Math::Basic :constants;

=over

=item e

constant Num Math::Basic::e

The constant C<e>, roughly equal to C<2.71828182845905>.

=item euler_constant

constant Num Math::Basic::γ
constant Num Math::Basic::euler_constant

The Euler constant (or Euler-Mascheroni constant or simply γ), roughly
equal to C<0.57721566490153286>. This constant should not be confused
with C<e>.

=item golden_ratio

constant Num Math::Basic::φ
constant Num Math::Basic::phi
constant Num Math::Basic::golden_ratio

The golden ratio, roughly equal to C<1.6180339887498948>.

=item i

constant Complex Math::Basic::i

The constant C<i>, which is defined as the square root of C<-1>.

=item one

constant Complex Math::Basic::one

The constant value C<1>.

=item pi

constant Num Math::Basic::π
constant Num Math::Basic::pi

The constant C<pi>, roughly equal to C<3.14159265358979>.

=item zero

constant Complex Math::Basic::zero

The constant value C<0>.

=back

------------------------

Yes, I've spotted the bug in one and zero being complex for no good reason.

If you think that we should change to sigiled constants, then I will
make it:

------------------------

=head2 Constants

To export the constants provided by C<Math::Basic> use the C<:constants>
tag when importing:

use Math::Basic :constants;

=over

=item $e

constant Num $Math::Basic::e

The constant C<e>, roughly equal to C<2.71828182845905>.

=item $euler_constant

constant Num $Math::Basic::γ
constant Num $Math::Basic::euler_constant

The Euler constant (or Euler-Mascheroni constant or simply γ), roughly
equal to C<0.57721566490153286>. This constant should not be confused
with C<e>.

=item $golden_ratio

constant Num $Math::Basic::φ
constant Num $Math::Basic::phi
constant Num $Math::Basic::golden_ratio

The golden ratio, roughly equal to C<1.6180339887498948>.

=item $i

constant Complex $Math::Basic::i

The constant C<i>, which is defined as the square root of C<-1>.

=item $one

constant Int $Math::Basic::one

The constant value C<1>.

=item $pi

constant Num $Math::Basic::π
constant Num $Math::Basic::pi

The constant C<pi>, roughly equal to C<3.14159265358979>.

=item $zero

constant Int $Math::Basic::zero

The constant value C<0>.

=back

------------------------

0 new messages