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