Author: lwall
Date: 2009-02-27 19:24:47 +0100 (Fri, 27 Feb 2009)
New Revision: 25626

Modified:
   docs/Perl6/Spec/S04-control.pod
Log:
Document new lift statement for writing generic multis


Modified: docs/Perl6/Spec/S04-control.pod
===================================================================
--- docs/Perl6/Spec/S04-control.pod     2009-02-27 17:47:30 UTC (rev 25625)
+++ docs/Perl6/Spec/S04-control.pod     2009-02-27 18:24:47 UTC (rev 25626)
@@ -12,9 +12,9 @@
 
   Maintainer: Larry Wall <la...@wall.org>
   Date: 19 Aug 2004
-  Last Modified: 27 Dec 2008
+  Last Modified: 27 Feb 2008
   Number: 4
-  Version: 71
+  Version: 72
 
 This document summarizes Apocalypse 4, which covers the block and
 statement syntax of Perl.
@@ -571,7 +571,7 @@
     # Not an error: Equivalent to "if foo() -> $x { say $x }"
     { say $^x } if foo();
 
-=head2 The gather statement
+=head2 The C<gather> statement prefix
 
 A variant of C<do> is C<gather>.  Like C<do>, it is followed by a
 statement or block, and executes it once.  Unlike C<do>, it evaluates
@@ -638,6 +638,40 @@
 C<Capture> object is generated, not when it is bound (which could
 happen more than once).
 
+=head2 The C<lift> statement prefix
+
+When writing generic multi routines you often want to write a bit of
+code whose meaning is dependent on the context of the caller.  It's
+somewhat like virtual methods where the actual call depends on the type
+of the invocant, but here the "invocant" is really the lexical scope of
+the caller, and the virtual calls are name bindings.  Within a lift,
+special rules apply to how names are looked up.  Only names defined
+in the lexical scope of the immediately surrounding routine are considered 
concrete.
+All other names (including implicit names of operators) are looked up
+in the lexical scope of the caller when we actually know who the caller
+is at run time.  (Note the caller can vary from call to call!)
+Through this mechanism, a generic multi can redirect execution to
+a more specific version, but the candidate list for this redirection
+is determined by the caller, not by the lexical scope of the multi,
+which can't see the caller's lexical scope except through the CALLER::
+pseudo package.  For example, Perl forces generic C<eq> to coerce to
+string comparison, like this:
+
+    proto infix:<eq> (Any $a, Any $b)  { lift ~$a eq ~$b }             # 
user's eq, user's ~
+    multi infix:<eq> (Whatever, Any $b)        { -> $a { lift $a eq $b } }     
# user's eq
+    multi infix:<eq> (Any $a, Whatever)        { -> $b { lift $a eq $b } }     
# user's eq
+    multi infix:<eq> (&f:($), Any $b)  { -> $a { lift f($a) eq $b } }  # 
user's eq
+    multi infix:<eq> (Str $a, Str $b)  { !Str::leg($a, $b) }           # 
primitive leg, primitive !
+
+
+Note that in each piec of lifted code there are references to
+variables defined in the multi, such as C<$a>, C<$b>, and C<&f>.
+These are taken at face value.  Everything else within a lift is
+assumed to mean something in the caller's context.  (This implies
+that there are some errors that would ordinarily be found at
+compile time that cannot be found until we know what the caller's
+lexical scope looks like at run time.  That's okay.)
+
 =head2 Other C<do>-like forms
 
 Other similar C<Code>-only forms may also take bare statements,

Reply via email to