Author: larry
Date: Tue Dec 19 01:02:59 2006
New Revision: 13494

Modified:
   doc/trunk/design/syn/S06.pod

Log:
Rehuffmanized call/goto to callmumble/nextmumble at suggestion of TheDamian++.
Eliminated the capture forms since unary |$args is just fine for that.
Changed interaction of normal sigs and capture sigs to deal with ambiguities
pointed out by luqui++ on #perl6.  Dual mapping now requires subsig syntax
so we can express invocants and multi types adequately.  No longer a
requirement to support binding of partially bound captures.


Modified: doc/trunk/design/syn/S06.pod
==============================================================================
--- doc/trunk/design/syn/S06.pod        (original)
+++ doc/trunk/design/syn/S06.pod        Tue Dec 19 01:02:59 2006
@@ -15,7 +15,7 @@
   Date: 21 Mar 2003
   Last Modified: 18 Dec 2006
   Number: 6
-  Version: 64
+  Version: 65
 
 
 This document summarizes Apocalypse 6, which covers subroutines and the
@@ -703,29 +703,39 @@
 parameter marked with a C<|>.
 
     sub bar ($a,$b,$c,:$mice) { say $mice }
-    sub foo (|$args) { say |$args.perl; &bar.callc($args); }
+    sub foo (|$args) { say $args.perl; &bar.callwith(|$args); }
 
-The C<.callc> method of C<Code> objects takes a C<Capture> argument.
-The C<.callv> method accepts an ordinary variadic argument list, so the
-following is equivalent:
+This prints:
 
-    sub foo (|$args) { say |$args.perl; &bar.callv(|$args); }
+    foo 1,2,3,:mice<blind>;     # says "\(1,2,3,:mice<blind>)" then "blind"
 
-In either case, the wrapped routine is called
-without introducing an official C<CALLER> frame, and produces:
+As demonstrated above, the capture may be interpolated into another
+call's arguments.  (The C<|> prefix is described in the next section.)
+Use of C<callwith> allows the routine to be called without introducing
+an official C<CALLER> frame.  For more see "Wrapping" below.
 
-    foo 1,2,3,:mice<blind>;     # says "\(1,2,3,:mice<blind>)" then "blind"
+It is allowed to rebind the parameters within the signature, but
+only as a subsignature of the capture argument:
+
+    sub compare (|$args (Num $x, Num $y --> Bool)) { ... }
+
+For all normal declarative purposes (invocants and multiple dispatch
+types, for instance), the inner signature is treated as the entire
+signature:
 
-It is allowed to specify additional parameters within the signature.
-The C<Capture> binding merely takes a snapshot of what's left of
-the C<Capture> at that point and then continues binding as if the
-C<Capture> parameter weren't there:
+    method addto (|$args ($self: @x)) { trace($args); $self += [+] @x }
 
-    sub compare (|$args, Num $x, Num $y --> Bool) { ... }
+The inner signature is not required for non-multies since there can
+only be one candidate, but for multiple dispatch the inner signature
+is required at least for its types, or the declaration would not know
+what signature to match against.
+
+    multi foo (|$args (Int; Bool?, *@, *%)) { reallyintfoo($args) }
+    multi foo (|$args (Str; Bool?, *@, *%)) { reallystrfoo($args) }
 
 =head2 Flattening argument lists
 
-The unary C<|> operator casts its arguments to a C<Capture>
+The unary C<|> operator casts its argument to a C<Capture>
 object, then splices that capture into the argument list
 it occurs in.  To get the same effect on multiple arguments you
 can use the C<< |« >> hyperoperator.
@@ -1776,6 +1786,7 @@
     trait_verb:<of>
     trait_auxiliary:<is>
     scope_declarator:<my>
+    statement_prefix:<do>
     statement_control:<if>
     statement_modifier:<if>
     infix_prefix_meta_operator:<!>
@@ -2118,24 +2129,25 @@
 
 =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> and C<callv> functions 
will invoke
-the original routine, but do not introduce an official C<CALLER> frame:
+Every C<Routine> object has a C<.wrap> method. This method expects a
+single C<Code> argument. Within the code, the special C<callsame>,
+C<callwith>, C<nextsame> and C<nextwith> 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( { callv( ($^t-32)/1.8 ) } );
+    $handle = &thermo.wrap( { callwith( ($^t-32)/1.8 ) } );
 
-The C<callv> function lets you pass your own arguments to the wrapped
-function.  The C<call> function takes an optional C<Capture> argument,
-with no arguments it implicitly passes the original argument list
-through unchanged.
+The C<callwith> function lets you pass your own arguments to the wrapped
+function.  The C<callsame> function takes no argument; it
+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> or C<callv> invokes the 
previous
-version of the routine. In other words, the call to C<.wrap> has more
-or less the same effect as:
+argument, and arranges that any call to C<callsame>, C<callwith>,
+C<nextsame> or C<nextwith> invokes the previous version of the
+routine. In other words, the call to C<.wrap> has more or less the
+same effect as:
 
     &old_thermo := &thermo;
     &thermo := sub ($t) { old_thermo( ($t-32)/1.8 ) }
@@ -2155,52 +2167,45 @@
 
     # Add a wrapper to convert from Kelvin
     # wrapper self-unwraps at end of current scope
-    temp &thermo.wrap( { callv($^t + 273.16) } );
+    temp &thermo.wrap( { callwith($^t + 273.16) } );
 
 The entire argument list may be captured by binding to a C<Capture> parameter.
-It can then be passed to C<call> using that name:
+It can then be passed to C<callwith> using that name:
 
     # Double the return value for &thermo
-    &thermo.wrap( -> |$args { call($args) * 2 } );
+    &thermo.wrap( -> |$args { callwith(|$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 one of its C<call> method:
+C<Code> object by passing the C<Capture> to its C<callwith> method:
 
     # Transparently redirect all calls to &thermo to &other_thermo
-    &thermo.wrap( sub (|$args) { &other_thermo.callv(|$args) } );
+    &thermo.wrap( sub (|$args) { &other_thermo.callwith(|$args) } );
 
 or more briefly:
 
-    &thermo.wrap( -> |$args { &other_thermo.callc($args) } );
-
-or even more briefly:
-
-    &thermo.wrap( { &other_thermo.call } );
+    &thermo.wrap( { &other_thermo.callsame } );
 
-Outside a wrapper, the various C<call> and C<goto> functions and
-methods implicitly call the next-most-likely method or multi-sub;
-see S12 for details.
+Since the method versions of C<callsame>, C<callwith>, C<nextsame>,
+and C<nextwith> specify an explicit destination, their semantics do
+not change outside of wrappers.  However, the corresponding functions
+have no explicit destination, so instead they 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 := callc($args);
+    my |$retval := callwith(|$args);
     ... # postprocessing
     return |$retval;
 
 Alternately, you may prevent any return at all by using the variants
-C<goto>, C<gotoc> and C<gotov>.  Arguments are passed just as with
-C<call>, C<callc>, and C<callv>, but a tail call is explicitly
-enforced; any following code will be unreached.  The C<callc> and
-C<gotoc> variants take a single optional C<Capture> argument supplying
-the new argument list; if not supplied, the incoming C<Capture> is
-passed verbatim (regardless of any capture bindings in the signature).
-You may also use the C<callv> or C<gotov> variants to pass an ordinary
-variadic argument list to the wrapped function.  Use C<< prefix:<|>
->> to incorporate a capture (such as the original argument list)
-into the new argument list.
+C<nextsame> and C<nextwith>.  Arguments are passed just as with
+C<callsame> and C<callwith>, but a tail call is explicitly enforced;
+any code following the call will be unreached, as if a return had
+been executed there before calling into the destination routine.
+Within a method C<nextsame> is equivalent to C<next METHOD>.
 
 =head2 The C<&?ROUTINE> object
 

Reply via email to