Author: lwall
Date: 2010-07-09 18:41:04 +0200 (Fri, 09 Jul 2010)
New Revision: 31593
Modified:
docs/Perl6/Spec/S05-regex.pod
docs/Perl6/Spec/S06-routines.pod
Log:
[S05,S06] more refinements to {*}
Modified: docs/Perl6/Spec/S05-regex.pod
===================================================================
--- docs/Perl6/Spec/S05-regex.pod 2010-07-09 15:37:27 UTC (rev 31592)
+++ docs/Perl6/Spec/S05-regex.pod 2010-07-09 16:41:04 UTC (rev 31593)
@@ -16,8 +16,8 @@
Created: 24 Jun 2002
- Last Modified: 8 Jul 2010
- Version: 126
+ Last Modified: 9 Jul 2010
+ Version: 127
This document summarizes Apocalypse 5, which is about the new regex
syntax. We now try to call them I<regex> rather than "regular
@@ -1147,13 +1147,18 @@
tie, a normal multiple dispatch is made using the arguments to the
remaining variants, assuming they can be differentiated by type.
-The proto calls into the subdispatcher when it sees a C<*> that
-cannot be a quantifier and is the only thing in its bracket. Therefore
+The C<proto> calls into the subdispatcher when it sees a C<*> that
+cannot be a quantifier and is the only thing in its block. Therefore
you can put items before and after the subdispatch by putting
-the C<*> into square brackets:
+the C<*> into curlies:
-proto token foo { <prestuff> [*] <poststuff> }
+ proto token foo { <prestuff> {*} <poststuff> }
+This works only in a proto. See L<S06> for a discussion of the
+semantics of C<{*}>. (Unlike a proto sub, a proto regex
+automatically remembers the return values from C<{*}> because
+they are carried along with the match cursor.)
+
=item *
The use of a hash variable in patterns is reserved.
Modified: docs/Perl6/Spec/S06-routines.pod
===================================================================
--- docs/Perl6/Spec/S06-routines.pod 2010-07-09 15:37:27 UTC (rev 31592)
+++ docs/Perl6/Spec/S06-routines.pod 2010-07-09 16:41:04 UTC (rev 31593)
@@ -16,8 +16,8 @@
Created: 21 Mar 2003
- Last Modified: 8 Jul 2010
- Version: 136
+ Last Modified: 9 Jul 2010
+ Version: 137
This document summarizes Apocalypse 6, which covers subroutines and the
new type system.
@@ -99,7 +99,7 @@
and dispatches them according to the rules of multiple dispatch as defined
for each of the various dispatchers.
-This default behavior is implied by a statement consisting of a single
+This default behavior is implied by a block containing of a single
C<*> (that is, a "whatever"). Hence the typical proto will simply
have a body of C<{*}>.
@@ -108,10 +108,10 @@
(We don't use C<...> for that because it would fail at run time,
and proto blocks are not stubs, but are intended to be executed.)
-Other statements may be inserted before and after the C<*>
+Other statements may be inserted before and after the C<{*}>
statement to capture control before or after the multi dispatch:
- proto foo ($a,$b) { say "Called with $a $b"; *; say "Returning"; }
+ proto foo ($a,$b) { say "Called with $a $b"; {*}; say "Returning"; }
(That proto is only good for multis with side effects and no return
value, since it returns the result of C<say>, which might not be what
@@ -143,33 +143,45 @@
Also, the old semantics of C<proto> providing the most-default multi body
is hereby deprecated. Default multis should be marked with "C<is default>".
-It is still possible to provide default behavior in the proto, however, by
-use of C<callsame> rather than C<nextsame>:
+It is still possible to provide default behavior in the proto, however:
- my proto sub foo () {
- do-something-before();
- my |$cap = (*); # call into the managed set, then come back
- do-something-after();
- return |$cap;
+ my proto sub foo (@args) {
+ do-something-before(@args);
+ {*} # call into the managed set, then come back
+ do-something-after(@args);
}
-or more simply:
+Note that this returns the value of do-something-after(), not the multi.
+There are two ways to get around that. Here's one way:
- my proto sub foo () {
- ENTER do-something-before();
- *;
- LEAVE do-something-after();
+ my proto sub foo (@args) {
+ ENTER do-something-before(@args);
+ {*}
+ LEAVE do-something-after(@args);
}
-Note that in the first example the C<*> must be placed into a
-context where it is a standalone statement in order to get its
-return value.
+Alternately, you can spell out what C<{*}> is actually sugar for,
+which would be some dispatcher macro such as:
+ my proto sub foo (|$cap (@args)) {
+ do-something-before(@args);
+ my |$retval = MULTI-DISPATCH-CALLWITH($?ROUTINE,$cap);
+ do-something-after(@args);
+ return |$retval;
+ }
+
+which optimizes (we hope) to an inlined multidispatcher to locate all
+the candidates for these arguments (hopefully memoized), create the dynamic
+scope of a dispatch, start the dispatch, manage C<callnext> and C<lastcall>
+semantics, and return the result of whichever C<multi> succeeded, if any.
+
+Which why we have C<{*}> instead.
+
Another common variant would be to propagate control to the
outer/higher routine that would have been found if this one didn't
exist:
- my proto method foo { *; UNDO nextsame; } # failover to super foo
+ my proto method foo { {*}; UNDO nextsame; } # failover to super foo
Note that, in addition to making multis work similarly to each other,
the new proto semantics greatly simplify top-level dispatchers, which